-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(runner): raise an error with detailed info about a found issue (#…
- Loading branch information
Showing
18 changed files
with
306 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { HttpMethod, Severity } from '@sec-tester/scan'; | ||
|
||
export const issueWithoutResourcesText = `Issue in Bright UI: http://app.neuralegion.com/scans/pDzxcEXQC8df1fcz1QwPf9/issues/pDzxcEXQC8df1fcz1QwPf9 | ||
Name: Database connection crashed | ||
Severity: Medium | ||
Remediation: | ||
The best way to protect against those kind of issues is making sure the Database resources are sufficient | ||
Details: | ||
Cross-site request forgery is a type of malicious website exploit.`; | ||
export const issueWithoutResources = { | ||
id: 'pDzxcEXQC8df1fcz1QwPf9', | ||
order: 1, | ||
details: 'Cross-site request forgery is a type of malicious website exploit.', | ||
name: 'Database connection crashed', | ||
severity: Severity.MEDIUM, | ||
protocol: 'http', | ||
remedy: | ||
'The best way to protect against those kind of issues is making sure the Database resources are sufficient', | ||
cvss: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L', | ||
time: new Date(), | ||
originalRequest: { | ||
method: HttpMethod.GET, | ||
url: 'https://brokencrystals.com/' | ||
}, | ||
request: { | ||
method: HttpMethod.GET, | ||
url: 'https://brokencrystals.com/' | ||
}, | ||
link: 'http://app.neuralegion.com/scans/pDzxcEXQC8df1fcz1QwPf9/issues/pDzxcEXQC8df1fcz1QwPf9' | ||
}; | ||
|
||
export const fullyDescribedIssueText = `${issueWithoutResourcesText} | ||
Extra Details: | ||
● Missing Strict-Transport-Security Header | ||
\tThe engine detected a missing Strict-Transport-Security header, which might cause data to be sent insecurely from the client to the server. | ||
\tLinks: | ||
\t● https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts | ||
References: | ||
● https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts`; | ||
export const fullyDescribedIssue = { | ||
...issueWithoutResources, | ||
comments: [ | ||
{ | ||
headline: 'Missing Strict-Transport-Security Header', | ||
text: 'The engine detected a missing Strict-Transport-Security header, which might cause data to be sent insecurely from the client to the server.', | ||
links: [ | ||
'https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts' | ||
] | ||
} | ||
], | ||
resources: [ | ||
'https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts' | ||
] | ||
}; | ||
export const issueWithoutExtraInfoText = `${issueWithoutResourcesText} | ||
References: | ||
● https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts`; | ||
export const issueWithoutExtraInfo = { | ||
...issueWithoutResources, | ||
resources: [ | ||
'https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#hsts' | ||
] | ||
}; |
44 changes: 44 additions & 0 deletions
44
packages/reporter/src/formatters/PlainTextFormatter.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { PlainTextFormatter } from './PlainTextFormatter'; | ||
import { | ||
fullyDescribedIssue, | ||
fullyDescribedIssueText, | ||
issueWithoutExtraInfo, | ||
issueWithoutExtraInfoText, | ||
issueWithoutResources, | ||
issueWithoutResourcesText | ||
} from '../__fixtures__/issues'; | ||
import { Issue } from '@sec-tester/scan'; | ||
|
||
describe('PlainTextFormatter', () => { | ||
let formatter!: PlainTextFormatter; | ||
|
||
beforeEach(() => { | ||
formatter = new PlainTextFormatter(); | ||
}); | ||
|
||
describe('format', () => { | ||
it.each([ | ||
{ | ||
input: fullyDescribedIssue, | ||
expected: fullyDescribedIssueText, | ||
title: 'fully described issue' | ||
}, | ||
{ | ||
input: issueWithoutExtraInfo, | ||
expected: issueWithoutExtraInfoText, | ||
title: 'issue without extra info' | ||
}, | ||
{ | ||
input: issueWithoutResources, | ||
expected: issueWithoutResourcesText, | ||
title: 'issue without resources' | ||
} | ||
])('should format $title', ({ input, expected }) => { | ||
// act | ||
const result = formatter.format(input as Issue); | ||
|
||
// assert | ||
expect(result).toEqual(expected); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { Formatter } from '../lib'; | ||
import { Comment, Issue } from '@sec-tester/scan'; | ||
import { format } from 'util'; | ||
|
||
export class PlainTextFormatter implements Formatter { | ||
private readonly BULLET_POINT = '●'; | ||
private readonly NEW_LINE = '\n'; | ||
private readonly TABULATION = '\t'; | ||
|
||
public format(issue: Issue): string { | ||
const { | ||
link, | ||
name, | ||
severity, | ||
remedy, | ||
details, | ||
comments = [], | ||
resources = [] | ||
} = issue; | ||
const template = this.generateTemplate({ | ||
extraInfo: comments.length > 0, | ||
references: resources.length > 0 | ||
}); | ||
|
||
const message = format( | ||
template, | ||
link, | ||
name, | ||
severity, | ||
remedy, | ||
details, | ||
this.formatList(comments, comment => this.formatExtraInfo(comment)), | ||
this.formatList(resources) | ||
); | ||
|
||
return message.trim(); | ||
} | ||
|
||
private generateTemplate(options: { | ||
extraInfo: boolean; | ||
references: boolean; | ||
}): string { | ||
return ` | ||
Issue in Bright UI: %s | ||
Name: %s | ||
Severity: %s | ||
Remediation: | ||
%s | ||
Details: | ||
%s${options.extraInfo ? `\nExtra Details:\n%s` : ''}${ | ||
options.references ? `\nReferences:\n%s` : '' | ||
}`.trim(); | ||
} | ||
|
||
private formatExtraInfo({ headline, text = '', links = [] }: Comment) { | ||
const footer = links.length | ||
? this.combineList(['Links:', this.formatList(links)]) | ||
: ''; | ||
const blocks = [text, footer].map(x => this.indent(x)); | ||
const document = this.combineList(blocks); | ||
|
||
return this.combineList([headline, document]); | ||
} | ||
|
||
private indent(x: string, length: number = 1) { | ||
const lines = x.split(this.NEW_LINE); | ||
|
||
return this.combineList( | ||
lines.map(line => `${this.TABULATION.repeat(length)}${line}`) | ||
); | ||
} | ||
|
||
private formatList<T>(list: T[], map?: (x: T) => string): string { | ||
const items = list.map( | ||
x => `${this.BULLET_POINT} ${typeof map == 'function' ? map(x) : x}` | ||
); | ||
|
||
return this.combineList(items); | ||
} | ||
|
||
private combineList(list: string[], sep?: string): string { | ||
return list.join(sep ?? this.NEW_LINE); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './PlainTextFormatter'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export { Reporter } from './lib'; | ||
export { PlainTextFormatter } from './formatters'; | ||
export { Reporter, Formatter } from './lib'; | ||
export { StdReporter } from './std'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Issue } from '@sec-tester/scan'; | ||
|
||
export interface Formatter { | ||
format(issue: Issue): string; | ||
} | ||
|
||
export const Formatter: unique symbol = Symbol('Formatter'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export { Reporter } from './Reporter'; | ||
export * from './Reporter'; | ||
export * from './Formatter'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Formatter } from '@sec-tester/reporter'; | ||
import { SecTesterError } from '@sec-tester/core'; | ||
import { Issue } from '@sec-tester/scan'; | ||
|
||
export class IssueFound extends SecTesterError { | ||
constructor(public readonly issue: Issue, formatter: Formatter) { | ||
super(`Target is vulnerable\n\n${formatter.format(issue)}`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.