java.lang.security.audit.xxe.documentbuilderfactory-disallow-doctype-decl-missing.documentbuilderfactory-disallow-doctype-decl-missing

profile photo of semgrepsemgrep
Author
unknown
Download Count*

DOCTYPE declarations are enabled for this DocumentBuilderFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false.

Run Locally

Run in CI

Defintion

rules:
  - id: documentbuilderfactory-disallow-doctype-decl-missing
    severity: ERROR
    metadata:
      cwe:
        - "CWE-611: Improper Restriction of XML External Entity Reference"
      owasp:
        - A04:2017 - XML External Entities (XXE)
        - A05:2021 - Security Misconfiguration
      asvs:
        section: V5 Validation, Sanitization and Encoding
        control_id: 5.5.2 Insecue XML Deserialization
        control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention
        version: "4"
      references:
        - https://semgrep.dev/blog/2022/xml-security-in-java
        - https://semgrep.dev/docs/cheat-sheets/java-xxe/
        - https://blog.sonarsource.com/secure-xml-processor
        - https://xerces.apache.org/xerces2-j/features.html
      category: security
      technology:
        - java
        - xml
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: LOW
      impact: HIGH
      confidence: HIGH
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - XML Injection
    message: DOCTYPE declarations are enabled for this DocumentBuilderFactory. This
      is vulnerable to XML external entity attacks. Disable this by setting the
      feature "http://apache.org/xml/features/disallow-doctype-decl" to true.
      Alternatively, allow DOCTYPE declarations and only prohibit external
      entities declarations. This can be done by setting the features
      "http://xml.org/sax/features/external-general-entities" and
      "http://xml.org/sax/features/external-parameter-entities" to false.
    mode: taint
    pattern-sources:
      - by-side-effect: true
        patterns:
          - pattern-either:
              - pattern: |
                  $FACTORY = DocumentBuilderFactory.newInstance();
              - patterns:
                  - pattern: $FACTORY
                  - pattern-inside: |
                      class $C {
                        ...
                        $V $FACTORY = DocumentBuilderFactory.newInstance();
                        ...
                      }
                  - pattern-not-inside: >
                      class $C {
                        ...
                        $V $FACTORY = DocumentBuilderFactory.newInstance();
                        static {
                          ...
                          $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
                          ...
                        }
                        ...
                      }
                  - pattern-not-inside: >
                      class $C {
                        ...
                        $V $FACTORY = DocumentBuilderFactory.newInstance();
                        static {
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false);
                          ...
                        }
                        ...
                      }
                  - pattern-not-inside: >
                      class $C {
                        ...
                        $V $FACTORY = DocumentBuilderFactory.newInstance();
                        static {
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false);
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
                          ...
                        }
                        ...
                      }
    pattern-sinks:
      - patterns:
          - pattern: $FACTORY.newDocumentBuilder();
    pattern-sanitizers:
      - by-side-effect: true
        pattern-either:
          - patterns:
              - pattern-either:
                  - pattern: >
                      $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
                      true);
                  - pattern: >
                      $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",
                      false);

                      ...

                      $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
                  - pattern: >
                      $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities",
                      false);

                      ...

                      $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false);
              - focus-metavariable: $FACTORY
          - patterns:
              - pattern-either:
                  - pattern-inside: >
                      class $C {
                        ...
                        $T $M(...) {
                          ...
                          $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
                          true);
                          ...
                        }
                        ...
                      }
                  - pattern-inside: >
                      class $C {
                        ...
                        $T $M(...) {
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities", false);
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
                          ...
                        }
                        ...
                      }
                  - pattern-inside: >
                      class $C {
                        ...
                        $T $M(...) {
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
                          ...
                          $FACTORY.setFeature("http://xml.org/sax/features/external-general-entities",false);
                          ...
                        }
                        ...
                      }
              - pattern: $M($X)
              - focus-metavariable: $X
    fix: >
      $FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
      true);

      $FACTORY.newDocumentBuilder();
    languages:
      - java

Examples

documentbuilderfactory-disallow-doctype-decl-missing.java

package example;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;


class GoodDocumentBuilderFactory {
    public void GoodDocumentBuilderFactory() throws  ParserConfigurationException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    public void GoodDocumentBuilderFactory2() throws  ParserConfigurationException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    public void GoodDocumentBuilderFactory3() throws  ParserConfigurationException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    public void GoodDocumentBuilderFactory4() throws  ParserConfigurationException {
        DocumentBuilderFactory factory = XmlUtils.getSecureDocumentBuilderFactory();
        //Deep semgrep could find issues like this
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        documentBuilder = factory.newDocumentBuilder();
    }
}

class BadDocumentBuilderFactory{
    public void BadDocumentBuilderFactory() throws  ParserConfigurationException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        //ruleid:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    public void BadDocumentBuilderFactory2() throws  ParserConfigurationException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("somethingElse", true);
        //ruleid:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }
}

class GoodDocumentBuilderFactoryStatic {

    private static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

    static {
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

}

class BadDocumentBuilderFactoryStatic {

    private static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

    static {
        dbf.setFeature("not-a-secure-feature", true);
    }

    public void doSomething(){
        //ruleid:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

}

class OneMoreGoodDocumentBuilderFactory {

    public void GoodDocumentBuilderFactory(boolean condition) throws  ParserConfigurationException {
        DocumentBuilderFactory dbf = null;
        
        if ( condition ) {
            dbf = DocumentBuilderFactor.newInstance();
        } else {
            dbf = newFactory();
        }
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    private DocumentBuilderFactory newFactory(){
        return DocumentBuilderFactory.newInstance();
    }

}

class OneMoreBadDocumentBuilderFactory {

    public void GoodDocumentBuilderFactory(boolean condition) throws  ParserConfigurationException {
        DocumentBuilderFactory dbf = null;
        
        if ( condition ) {
            dbf = DocumentBuilderFactory.newInstance();
        } else {
            dbf = newFactory();
        }
        //ruleid:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    private DocumentBuilderFactory newFactory(){
        return DocumentBuilderFactory.newInstance();
    }


}


class GoodDocumentBuilderFactoryCtr {

    private final DocumentBuilderFactory dbf;

    public GoodDocumentBuilderFactoryCtr() throws Exception {
        dbf = DocumentBuilderFactory.newInstance();
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }
}


class GoodDocumentBuilderFactoryCtr2 {
    public void somemethod() throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        setFeatures(dbf);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    private void setFeatures(DocumentBuilderFactory dbf) throws Exception {
        dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    }

}

class GoodDocumentBuilderFactoryCtr3 {
    public void somemethod() throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        setFeatures(dbf);
        //ok:documentbuilderfactory-disallow-doctype-decl-missing
        dbf.newDocumentBuilder();
    }

    private void setFeatures(DocumentBuilderFactory dbf) throws Exception {
        dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    }

}