javascript.express.security.audit.express-libxml-vm-noent.express-libxml-vm-noent
semgrep
Author
unknown
Download Count*
License
Detected use of parseXml() function with the noent
field set to true
. This can lead to an XML External Entities (XXE) attack if untrusted data is passed into it.
Run Locally
Run in CI
Defintion
rules:
- id: express-libxml-vm-noent
message: Detected use of parseXml() function with the `noent` field set to
`true`. This can lead to an XML External Entities (XXE) attack if
untrusted data is passed into it.
metadata:
references:
- https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
owasp:
- A04:2017 - XML External Entities (XXE)
- A05:2021 - Security Misconfiguration
cwe:
- "CWE-611: Improper Restriction of XML External Entity Reference"
category: security
technology:
- express
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
likelihood: LOW
impact: HIGH
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- XML Injection
languages:
- javascript
- typescript
severity: WARNING
patterns:
- pattern-either:
- patterns:
- pattern-either:
- pattern: $VM.runInContext("$CMD", ...)
- pattern: $VM.runInNewContext("$CMD", ...)
- pattern: $VM.runInThisContext("$CMD", ...)
- pattern: $VM.compileFunction("$CMD", ...)
- metavariable-pattern:
metavariable: $CMD
language: typescript
pattern-either:
- pattern: |
$LIBXML.parseXml($DATA, {..., noent: true, ...}, ...)
- patterns:
- pattern-inside: |
$OPTS = {..., noent: true, ...}
...
- pattern: $LIBXML.parseXml( $DATA, $OPTS )
- pattern: |
$LIBXML.parseXml($DATA, {..., noent: true, ...}, ...)
- patterns:
- pattern-inside: |
$OPTS = {..., noent: true, ...}
...
- pattern: $LIBXML.parseXml( $DATA, $OPTS )
Examples
express-libxml-vm-noent.js
function handleXmlUpload ({ file }: Request, res: Response, next: NextFunction) {
if (utils.endsWith(file?.originalname.toLowerCase(), '.xml')) {
if (file?.buffer && !utils.disableOnContainerEnv()) { // XXE attacks in Docker/Heroku containers regularly cause "segfault" crashes
const data = file.buffer.toString()
try {
const sandbox = { libxml, data }
vm.createContext(sandbox)
// ruleid: express-libxml-vm-noent
const xmlDoc = vm.runInContext('libxml.parseXml(data, { noblanks: true, noent: true, nocdata: true })', sandbox, { timeout: 2000 })
// ruleid: express-libxml-vm-noent
const xmlDoc = vm.runInContext("libxml.parseXml(data, { noblanks: true, noent: true, nocdata: true })", sandbox, { timeout: 2000 })
// ruleid: express-libxml-vm-noent
libxml.parseXml(data, { noblanks: true, noent: true, nocdata: true })
const xml_opts = { noblanks: true, noent: true, nocdata: true }
// ruleid: express-libxml-vm-noent
libxml.parseXml(data, xml_opts)
// ok: express-libxml-vm-noent
libxml.parseXml(data, { noblanks: true, nocdata: true })
const xmlString = xmlDoc.toString(false)
res.status(410)
next(new Error('B2B customer complaints via file upload have been deprecated for security reasons: ' + utils.trunc(xmlString, 400) + ' (' + file.originalname + ')'))
} catch (err) {
if (utils.contains(err.message, 'Script execution timed out')) {
res.status(503)
next(new Error('Sorry, we are temporarily not available! Please try again later.'))
} else {
res.status(410)
next(new Error('B2B customer complaints via file upload have been deprecated for security reasons: ' + err.message + ' (' + file.originalname + ')'))
}
}
} else {
res.status(410)
next(new Error('B2B customer complaints via file upload have been deprecated for security reasons (' + file?.originalname + ')'))
}
}
res.status(204).end()
}
Short Link: https://sg.run/n8Ag