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:
Maxim Laikine 2023-10-09 11:07:46 -07:00 коммит произвёл GitHub
Родитель 62cf7c2ff2
Коммит aa6707711b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 67 добавлений и 70 удалений

Просмотреть файл

@ -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',
};
}
}
}