javascript.sax.security.audit.sax-xxe.sax-xxe

Community Favorite
profile photo of semgrepsemgrep
Author
26,412
Download Count*

Use of 'ondoctype' in 'sax' library detected. By default, 'sax' won't do anything with custom DTD entity definitions. If you're implementing a custom DTD entity definition, be sure not to introduce XML External Entity (XXE) vulnerabilities, or be absolutely sure that external entities received from a trusted source while processing XML.

Run Locally

Run in CI

Defintion

rules:
  - id: sax-xxe
    message: Use of 'ondoctype' in 'sax' library detected. By default, 'sax' won't
      do anything with custom DTD entity definitions. If you're implementing a
      custom DTD entity definition, be sure not to introduce XML External Entity
      (XXE) vulnerabilities, or be absolutely sure that external entities
      received from a trusted source while processing XML.
    metadata:
      owasp:
        - A04:2017 - XML External Entities (XXE)
        - A05:2021 - Security Misconfiguration
      cwe:
        - "CWE-611: Improper Restriction of XML External Entity Reference"
      references:
        - https://github.com/Leonidas-from-XIV/node-xml2js/issues/415
        - https://github.com/isaacs/sax-js
      category: security
      technology:
        - sax
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - XML Injection
    languages:
      - javascript
      - typescript
    severity: WARNING
    pattern-either:
      - pattern: |
          require('sax');
          ...
          $PARSER.ondoctype = ...;
      - pattern: |-
          require('sax');
          ...
          $PARSER.on('doctype',...);

Examples

sax-xxe.js

function test1() {
    // ruleid: sax-xxe
    var sax = require("sax"),
    strict = false,
    parser = sax.parser(strict);

    parser.onattribute = function (attr) {
        doSmth(attr)
    };

    parser.ondoctype = function(dt) {
        processDocType(dt)
    }

    const xml = `<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [
    <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
    <username>&xxe;</username>`;

    parser.write(xml).close();
}

function test2() {
    // ruleid: sax-xxe
    var saxStream = require("sax").createStream(strict, options)

    saxStream.on("opentag", function (node) {
        // same object as above
    })

    saxStream.on("doctype", function (node) {
        processType(node)
    })

    fs.createReadStream("file.xml")
        .pipe(saxStream)
        .pipe(fs.createWriteStream("file-copy.xml"))
}

function okTest1() {
    // ok: sax-xxe
    var saxStream = require("sax").createStream(strict, options)

    saxStream.on("ontext", function (node) {
        // same object as above
    })

    fs.createReadStream("file.xml").pipe(saxStream).pipe(fs.createWriteStream("file-copy.xml"))
}