-
Notifications
You must be signed in to change notification settings - Fork 9
feat(CSAF2.1): #622 CSAF 2.1 add mandatory test 6.1.27.6 #626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import { Ajv } from 'ajv/dist/jtd.js' | ||
|
|
||
| const ajv = new Ajv() | ||
|
|
||
| /* | ||
| This is the jtd schema that needs to match the input document so that the | ||
| test is activated. If this schema doesn't match it normally means that the input | ||
| document does not validate against the csaf json schema or optional fields that | ||
| the test checks are not present. | ||
| */ | ||
| const inputSchema = /** @type {const} */ ({ | ||
| additionalProperties: true, | ||
| properties: { | ||
| document: { | ||
| additionalProperties: true, | ||
| properties: { | ||
| category: { | ||
| type: 'string', | ||
| }, | ||
| }, | ||
| }, | ||
| vulnerabilities: { | ||
| elements: { | ||
| additionalProperties: true, | ||
| optionalProperties: { | ||
| product_status: { | ||
| elements: { | ||
| additionalProperties: true, | ||
| properties: {}, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }) | ||
|
|
||
| const validate = ajv.compile(inputSchema) | ||
| /** | ||
| * @param {any} doc | ||
| */ | ||
| export function mandatoryTest_6_1_27_6(doc) { | ||
| /** @type {Array<{ message: string; instancePath: string }>} */ | ||
| const errors = [] | ||
| let isValid = true | ||
|
|
||
| if (!validate(doc)) return { errors, isValid } | ||
|
|
||
| const checkedDocumentCategories = new Set([ | ||
| 'csaf_security_advisory', | ||
| 'csaf_vex', | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. csaf_vex is not included in the relevant values |
||
| 'csaf_deprecated_security_advisory', | ||
| ]) | ||
|
|
||
| if (!checkedDocumentCategories.has(doc.document?.category)) { | ||
| return { errors, isValid } | ||
| } | ||
|
|
||
| const vulnerabilities = doc.vulnerabilities | ||
| if (Array.isArray(vulnerabilities)) { | ||
| vulnerabilities.forEach((vulnerability, vulnerabilityIndex) => { | ||
| if ( | ||
| !vulnerability.product_status || | ||
| vulnerability.product_status.length === 0 | ||
| ) { | ||
| isValid = false | ||
| errors.push({ | ||
| instancePath: `/vulnerabilities/${vulnerabilityIndex}`, | ||
| message: 'needs a `notes` attribute', | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. needa a |
||
| }) | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| return { errors, isValid } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import assert from 'node:assert/strict' | ||
| import { mandatoryTest_6_1_27_6 } from '../../csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_6.js' | ||
|
|
||
| describe('mandatoryTest_6_1_27_6', function () { | ||
| it('only runs on relevant documents', function () { | ||
| assert.equal(mandatoryTest_6_1_27_6({ document: 'mydoc' }).isValid, true) | ||
| }) | ||
|
|
||
| it('returns valid for documents with irrelevant category', function () { | ||
| assert.equal( | ||
| mandatoryTest_6_1_27_6({ | ||
| document: { category: 'csaf_base' }, | ||
| vulnerabilities: [{}], | ||
| }).isValid, | ||
| true | ||
| ) | ||
| }) | ||
|
|
||
| it('returns invalid when vulnerability has no product_status', function () { | ||
| const result = mandatoryTest_6_1_27_6({ | ||
| document: { category: 'csaf_security_advisory' }, | ||
| vulnerabilities: [{}], | ||
| }) | ||
| assert.equal(result.isValid, false) | ||
| assert.equal(result.errors.length, 1) | ||
| }) | ||
|
|
||
| it('returns invalid when vulnerability has empty product_status array', function () { | ||
| const result = mandatoryTest_6_1_27_6({ | ||
| document: { category: 'csaf_security_advisory' }, | ||
| vulnerabilities: [{ product_status: [] }], | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. “product_status” should also be an object rather than an array |
||
| }) | ||
| assert.equal(result.isValid, false) | ||
| assert.equal(result.errors.length, 1) | ||
| }) | ||
| }) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
product_status is an object with optional sub-properties, not an array