Skip scanning unknown authenticated URLs (#2492)
#### Details Skip scanning unknown authenticated URLs #### Pull request checklist <!-- If a checklist item is not applicable to this change, write "n/a" in the checkbox --> - [ ] Addresses an existing issue: Fixes #0000 - [x] Added relevant unit test for your changes. (`yarn test`) - [ ] Verified code coverage for the changes made. Check coverage report at: `<rootDir>/test-results/unit/coverage` - [ ] Ran precheckin (`yarn precheckin`) - [x] Validated in an Azure resource group
This commit is contained in:
Родитель
62cf7c2ff2
Коммит
aa6707711b
|
@ -69,8 +69,6 @@ describe(PageScanProcessor, () => {
|
|||
const loadedUrl = 'http://example.org';
|
||||
pageMetadata = {
|
||||
allowed: false,
|
||||
foreignLocation: true,
|
||||
authentication: false,
|
||||
loadedUrl,
|
||||
} as PageMetadata;
|
||||
websiteScanResult = { discoveryPatterns: [generatedDiscoveryPattern] } as WebsiteScanResult;
|
||||
|
@ -81,7 +79,7 @@ describe(PageScanProcessor, () => {
|
|||
};
|
||||
axeScanResults = {
|
||||
unscannable: true,
|
||||
error: `The scan URL location is not allowed ${loadedUrl}`,
|
||||
error: `The scan URL location is not allowed and will not be processed further. URL ${loadedUrl}`,
|
||||
};
|
||||
pageMetadataGeneratorMock.reset();
|
||||
pageMetadataGeneratorMock
|
||||
|
@ -99,7 +97,6 @@ describe(PageScanProcessor, () => {
|
|||
const loadedUrl = 'http://example.org';
|
||||
pageMetadata = {
|
||||
foreignLocation: true,
|
||||
authentication: false,
|
||||
loadedUrl,
|
||||
} as PageMetadata;
|
||||
websiteScanResult = { discoveryPatterns: [generatedDiscoveryPattern] } as WebsiteScanResult;
|
||||
|
@ -110,7 +107,7 @@ describe(PageScanProcessor, () => {
|
|||
};
|
||||
axeScanResults = {
|
||||
unscannable: true,
|
||||
error: `The scan URL was redirected to foreign location ${loadedUrl}`,
|
||||
error: `The scan URL was redirected to foreign location and will not be processed further. URL ${loadedUrl}`,
|
||||
};
|
||||
pageMetadataGeneratorMock.reset();
|
||||
pageMetadataGeneratorMock
|
||||
|
@ -124,6 +121,48 @@ describe(PageScanProcessor, () => {
|
|||
expect(results).toEqual(axeScanResults);
|
||||
});
|
||||
|
||||
it('skip page scan for foreign authentication location', async () => {
|
||||
const loadedUrl = 'http://example.org';
|
||||
pageMetadata = {
|
||||
foreignLocation: true,
|
||||
authentication: true,
|
||||
authenticationType: 'undetermined',
|
||||
loadedUrl,
|
||||
} as PageMetadata;
|
||||
websiteScanResult = { discoveryPatterns: [generatedDiscoveryPattern] } as WebsiteScanResult;
|
||||
const scanMetadata = {
|
||||
url,
|
||||
id: 'id',
|
||||
deepScan: true,
|
||||
};
|
||||
axeScanResults = {
|
||||
unscannable: true,
|
||||
error: `The scan URL was redirected to foreign location and will not be processed further. URL ${loadedUrl}`,
|
||||
};
|
||||
pageMetadataGeneratorMock.reset();
|
||||
pageMetadataGeneratorMock
|
||||
.setup((o) => o.getMetadata(url, pageMock.object, websiteScanResult))
|
||||
.returns(() => Promise.resolve(pageMetadata))
|
||||
.verifiable();
|
||||
setupClosePage();
|
||||
pageMock
|
||||
.setup((p) => p.authenticationResult)
|
||||
.returns(() => undefined)
|
||||
.verifiable();
|
||||
const expectedPageScanResult = cloneDeep({
|
||||
...pageScanResult,
|
||||
authentication: {
|
||||
detected: 'undetermined',
|
||||
state: 'unauthenticated',
|
||||
},
|
||||
});
|
||||
|
||||
const results = await testSubject.scan(scanMetadata, pageScanResult, websiteScanResult);
|
||||
|
||||
expect(pageScanResult).toEqual(expectedPageScanResult);
|
||||
expect(results).toEqual(axeScanResults);
|
||||
});
|
||||
|
||||
it('scan with authentication enabled', async () => {
|
||||
const scanMetadata = {
|
||||
url: url,
|
||||
|
@ -163,9 +202,6 @@ describe(PageScanProcessor, () => {
|
|||
.setup((p) => p.authenticationResult)
|
||||
.returns(() => authenticationResult)
|
||||
.verifiable();
|
||||
|
||||
const results = await testSubject.scan(scanMetadata, pageScanResult, websiteScanResult);
|
||||
|
||||
const expectedPageScanResult = cloneDeep({
|
||||
...pageScanResult,
|
||||
authentication: {
|
||||
|
@ -174,50 +210,9 @@ describe(PageScanProcessor, () => {
|
|||
state: 'succeeded',
|
||||
},
|
||||
});
|
||||
expect(pageScanResult).toEqual(expectedPageScanResult);
|
||||
expect(results).toEqual(axeScanResults);
|
||||
});
|
||||
|
||||
it('scan with unknown authentication detected', async () => {
|
||||
const scanMetadata = {
|
||||
url: url,
|
||||
id: 'id',
|
||||
};
|
||||
axeScanResults = { ...axeScanResults, pageScreenshot, pageSnapshot };
|
||||
|
||||
pageMetadata = {
|
||||
foreignLocation: true,
|
||||
authentication: true,
|
||||
authenticationType: 'undetermined',
|
||||
} as PageMetadata;
|
||||
pageMetadataGeneratorMock.reset();
|
||||
pageMetadataGeneratorMock
|
||||
.setup((o) => o.getMetadata(url, pageMock.object, websiteScanResult))
|
||||
.returns(() => Promise.resolve(pageMetadata))
|
||||
.verifiable();
|
||||
|
||||
setupNavigatePage(url);
|
||||
setupGetPageState();
|
||||
setupClosePage();
|
||||
axeScannerMock
|
||||
.setup((s) => s.scan(pageMock.object))
|
||||
.returns(() => Promise.resolve(axeScanResults))
|
||||
.verifiable();
|
||||
deepScannerMock.setup((o) => o.runDeepScan(It.isAny(), It.isAny(), websiteScanResult, It.isAny())).verifiable();
|
||||
pageMock
|
||||
.setup((p) => p.authenticationResult)
|
||||
.returns(() => undefined)
|
||||
.verifiable();
|
||||
|
||||
const results = await testSubject.scan(scanMetadata, pageScanResult, websiteScanResult);
|
||||
|
||||
const expectedPageScanResult = cloneDeep({
|
||||
...pageScanResult,
|
||||
authentication: {
|
||||
detected: 'undetermined',
|
||||
state: 'unauthenticated',
|
||||
},
|
||||
});
|
||||
expect(pageScanResult).toEqual(expectedPageScanResult);
|
||||
expect(results).toEqual(axeScanResults);
|
||||
});
|
||||
|
|
|
@ -32,15 +32,15 @@ export class PageScanProcessor {
|
|||
|
||||
const state = this.getScannableState(pageMetadata);
|
||||
if (state.unscannable === true) {
|
||||
this.setAuthenticationResult(pageMetadata, pageScanResult);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
const enableAuthentication = pageScanResult.authentication?.hint !== undefined;
|
||||
await this.page.navigate(runnerScanMetadata.url, { enableAuthentication });
|
||||
|
||||
if (pageMetadata.authentication === true) {
|
||||
this.setAuthenticationResult(pageMetadata, pageScanResult);
|
||||
}
|
||||
this.setAuthenticationResult(pageMetadata, pageScanResult);
|
||||
|
||||
if (!isEmpty(this.page.browserError)) {
|
||||
return { error: this.page.browserError, pageResponseCode: this.page.browserError.statusCode };
|
||||
|
@ -61,25 +61,28 @@ export class PageScanProcessor {
|
|||
private getScannableState(pageMetadata: PageMetadata): AxeScanResults {
|
||||
// Not allowed location
|
||||
if (pageMetadata.allowed === false) {
|
||||
this.logger.logWarn(`The scan URL location is not allowed.`, {
|
||||
this.logger.logWarn(`The scan URL location is not allowed and will not be processed further.`, {
|
||||
loadedUrl: pageMetadata.loadedUrl,
|
||||
});
|
||||
|
||||
return {
|
||||
unscannable: true,
|
||||
error: `The scan URL location is not allowed ${pageMetadata.loadedUrl}`,
|
||||
error: `The scan URL location is not allowed and will not be processed further. URL ${pageMetadata.loadedUrl}`,
|
||||
};
|
||||
}
|
||||
|
||||
// Redirected to foreign unauthenticated location
|
||||
if (pageMetadata.foreignLocation === true && pageMetadata.authentication !== true) {
|
||||
this.logger.logWarn(`The scan URL was redirected to foreign location and will not be processed future.`, {
|
||||
// Redirected to foreign location or foreign unknown authentication location
|
||||
if (
|
||||
pageMetadata.foreignLocation === true &&
|
||||
(pageMetadata.authentication !== true || pageMetadata.authenticationType === 'undetermined')
|
||||
) {
|
||||
this.logger.logWarn(`The scan URL was redirected to foreign location and will not be processed further.`, {
|
||||
loadedUrl: pageMetadata.loadedUrl,
|
||||
});
|
||||
|
||||
return {
|
||||
unscannable: true,
|
||||
error: `The scan URL was redirected to foreign location ${pageMetadata.loadedUrl}`,
|
||||
error: `The scan URL was redirected to foreign location and will not be processed further. URL ${pageMetadata.loadedUrl}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -99,24 +102,23 @@ export class PageScanProcessor {
|
|||
}
|
||||
|
||||
private setAuthenticationResult(pageMetadata: PageMetadata, pageScanResult: OnDemandPageScanResult): void {
|
||||
if (pageMetadata.authentication !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const authenticationResult = this.page.authenticationResult;
|
||||
if (pageMetadata.authenticationType === 'undetermined') {
|
||||
pageScanResult.authentication = {
|
||||
...pageScanResult.authentication,
|
||||
detected: pageMetadata.authenticationType,
|
||||
state: 'unauthenticated',
|
||||
};
|
||||
} else if (authenticationResult === undefined) {
|
||||
pageScanResult.authentication = {
|
||||
...pageScanResult.authentication,
|
||||
state: 'unauthenticated',
|
||||
};
|
||||
} else {
|
||||
if (authenticationResult !== undefined) {
|
||||
pageScanResult.authentication = {
|
||||
...pageScanResult.authentication,
|
||||
detected: authenticationResult.authenticationType,
|
||||
state: authenticationResult.authenticated === true ? 'succeeded' : 'failed',
|
||||
};
|
||||
} else {
|
||||
pageScanResult.authentication = {
|
||||
...pageScanResult.authentication,
|
||||
detected: pageMetadata.authenticationType,
|
||||
state: 'unauthenticated',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче