java.lang.security.audit.xxe.saxparserfactory-disallow-doctype-decl-missing.saxparserfactory-disallow-doctype-decl-missing
semgrep
Author
unknown
Download Count*
License
DOCTYPE declarations are enabled for this SAXParserFactory. 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. NOTE - The previous links are not meant to be clicked. They are the literal config key values that are supposed to be used to disable these features. For more information, see https://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory.
Run Locally
Run in CI
Defintion
rules:
- id: saxparserfactory-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 SAXParserFactory. 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. NOTE -
The previous links are not meant to be clicked. They are the literal
config key values that are supposed to be used to disable these features.
For more information, see
https://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory.
mode: taint
pattern-sources:
- by-side-effect: true
patterns:
- pattern-either:
- pattern: |
$FACTORY = SAXParserFactory.newInstance();
- patterns:
- pattern: $FACTORY
- pattern-inside: |
class $C {
...
$V $FACTORY = SAXParserFactory.newInstance();
...
}
- pattern-not-inside: >
class $C {
...
$V $FACTORY = SAXParserFactory.newInstance();
static {
...
$FACTORY.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
...
}
...
}
- pattern-not-inside: >
class $C {
...
$V $FACTORY = SAXParserFactory.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 = SAXParserFactory.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.newSAXParser();
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.newSAXParser();
languages:
- java
Examples
saxparserfactory-disallow-doctype-decl-missing.java
package example;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;
class GoodSAXParserFactory {
public void GoodSAXParserFactory() throws ParserConfigurationException {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
public void GoodSAXParserFactory2() throws ParserConfigurationException {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
public void GoodSAXParserFactory3() throws ParserConfigurationException {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
public void GoodSAXParserFactory4() throws ParserConfigurationException {
SAXParserFactory factory = XmlUtils.getSecureSAXParserFactory();
//Deep semgrep could find issues like this
//ok:saxparserfactory-disallow-doctype-decl-missing
saxparser = factory.newSAXParser();
}
}
class BadSAXParserFactory{
public void BadSAXParserFactory() throws ParserConfigurationException {
SAXParserFactory spf = SAXParserFactory.newInstance();
//ruleid:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
public void BadSAXParserFactory2() throws ParserConfigurationException {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("somethingElse", true);
//ruleid:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
}
class GoodSAXParserFactoryStatic {
private static SAXParserFactory spf = SAXParserFactory.newInstance();
static {
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
}
class BadSAXParserFactoryStatic {
private static SAXParserFactory spf = SAXParserFactory.newInstance();
static {
spf.setFeature("not-a-secure-feature", true);
}
public void doSomething(){
//ruleid:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
}
class OneMoreGoodSAXParserFactory {
public void GoodSAXParserFactory(boolean condition) throws ParserConfigurationException {
SAXParserFactory spf = null;
if ( condition ) {
spf = SAXParserFactor.newInstance();
} else {
spf = newFactory();
}
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
private SAXParserFactory newFactory(){
return SAXParserFactory.newInstance();
}
}
class OneMoreBadSAXParserFactory {
public void GoodSAXParserFactory(boolean condition) throws ParserConfigurationException {
SAXParserFactory spf = null;
if ( condition ) {
spf = SAXParserFactory.newInstance();
} else {
spf = newFactory();
}
//ruleid:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
private SAXParserFactory newFactory(){
return SAXParserFactory.newInstance();
}
}
class GoodSAXParserFactoryCtr {
private final SAXParserFactory spf;
public GoodSAXParserFactoryCtr() throws Exception {
spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
}
class GoodSAXParserFactoryCtr2 {
public void somemethod() throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
setFeatures(spf);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
private void setFeatures(SAXParserFactory spf) throws Exception {
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
}
}
class GoodSAXParserFactoryCtr3 {
public void somemethod() throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
setFeatures(spf);
//ok:saxparserfactory-disallow-doctype-decl-missing
spf.newSAXParser();
}
private void setFeatures(SAXParserFactory spf) throws Exception {
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
}
}
Short Link: https://sg.run/Gj32