Skip to content

Commit 7c34096

Browse files
authored
feat: XML Validator prevent parsing XXE (#1063)
prevent the XmlValidation from XXE parsing - prevent XML external entity (XXE) injection This is considered a security measure. fixes #1061 as described here: #1063 (comment) --------- Signed-off-by: Jan Kowalleck <[email protected]>
1 parent 309dd5a commit 7c34096

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

HISTORY.md

+7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ All notable changes to this project will be documented in this file.
66

77
<!-- add unreleased items here -->
88

9+
* Changed
10+
* The provided XML validation capabilities no longer supports external entities (via [#1063]; concerns [#1061])
11+
This is considered a security measure to prevent XML external entity (XXE) injection.
12+
13+
[#1061]: https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1061
14+
[#1063]: https://github.com/CycloneDX/cyclonedx-javascript-library/pull/1063
15+
916
## 6.6.1 -- 2024-05-06
1017

1118
* Fixed

src/validation/xmlValidator.node.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ async function getParser (): Promise<typeof parseXml> {
4848

4949
const xmlParseOptions: Readonly<ParserOptions> = Object.freeze({
5050
nonet: true,
51-
compact: true
51+
compact: true,
52+
noent: true // prevent https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1061
5253
})
5354

5455
export class XmlValidator extends BaseValidator {

tests/integration/Validation.XmlValidator.test.js

+54
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,59 @@ describe('Validation.XmlValidator', () => {
9999
const validationError = await validator.validate(input)
100100
assert.strictEqual(validationError, null)
101101
})
102+
103+
it('is not vulnerable to advisories/GHSA-mjr4-7xg5-pfvh', async () => {
104+
/* report:
105+
see https://github.com/advisories/GHSA-mjr4-7xg5-pfvh
106+
see https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1061
107+
*/
108+
const validator = new XmlValidator(version)
109+
/* POC payload:
110+
see https://research.jfrog.com/vulnerabilities/libxmljs2-attrs-type-confusion-rce-jfsa-2024-001034097/#poc
111+
*/
112+
const input = `<?xml version="1.0" encoding="UTF-8"?>
113+
<!DOCTYPE note
114+
[
115+
<!ENTITY writer "` + 'A'.repeat(0x1234) + `">
116+
]>
117+
<bom xmlns="http://cyclonedx.org/schema/bom/${version}">
118+
<components>
119+
<component type="library">
120+
<name>&writer;</name><!-- << XML external entity (XXE) injection -->
121+
<version>1.337</version>
122+
${version === '1.0' ? '<modified>false</modified>' : ''}
123+
</component>
124+
</components>
125+
</bom>`
126+
const validationError = await validator.validate(input)
127+
assert.strictEqual(validationError, null)
128+
})
129+
130+
it('is not vulnerable to advisories/GHSA-78h3-pg4x-j8cv', async () => {
131+
/* report:
132+
see https://github.com/advisories/GHSA-78h3-pg4x-j8cv
133+
see https://github.com/CycloneDX/cyclonedx-javascript-library/issues/1061
134+
*/
135+
const validator = new XmlValidator(version)
136+
/* POC payload:
137+
see https://research.jfrog.com/vulnerabilities/libxmljs2-namespaces-type-confusion-rce-jfsa-2024-001034098/#poc
138+
*/
139+
const input = `<?xml version="1.0" encoding="UTF-8"?>
140+
<!DOCTYPE note
141+
[
142+
<!ENTITY writer PUBLIC "` + 'A'.repeat(8) + 'B'.repeat(8) + 'C'.repeat(8) + 'D'.repeat(8) + 'P'.repeat(8) + `" "JFrog Security">
143+
]>
144+
<bom xmlns="http://cyclonedx.org/schema/bom/${version}">
145+
<components>
146+
<component type="library">
147+
<name>&writer;</name><!-- << XML external entity (XXE) injection -->
148+
<version>1.337</version>
149+
${version === '1.0' ? '<modified>false</modified>' : ''}
150+
</component>
151+
</components>
152+
</bom>`
153+
const validationError = await validator.validate(input)
154+
assert.strictEqual(validationError, null)
155+
})
102156
}))
103157
})

0 commit comments

Comments
 (0)