diff --git a/leshan-core/src/main/java/org/eclipse/leshan/core/model/DDFFileParser.java b/leshan-core/src/main/java/org/eclipse/leshan/core/model/DDFFileParser.java index ae07321738..93b1ccafa5 100644 --- a/leshan-core/src/main/java/org/eclipse/leshan/core/model/DDFFileParser.java +++ b/leshan-core/src/main/java/org/eclipse/leshan/core/model/DDFFileParser.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; +import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -75,12 +76,39 @@ public DDFFileParser(DDFFileValidatorFactory ddfFileValidatorFactory) { } private DDFFileParser(DDFFileValidator ddfValidator, DDFFileValidatorFactory ddfFileValidatorFactory) { - factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); + this.factory = createDocumentBuilderFactory(); this.ddfValidator = ddfValidator; this.ddfValidatorFactory = ddfFileValidatorFactory; } + protected DocumentBuilderFactory createDocumentBuilderFactory() { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + // Create Safe DocumentBuilderFactory (not vulnerable to XXE Attacks) + // ----------------------------------------------------------------- + // There is several recommendation from different source we try to apply all, even if some are maybe + // redundant. + + // from : + // https://semgrep.dev/docs/cheat-sheets/java-xxe/ + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + + // from : + // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxp-documentbuilderfactory-saxparserfactory-and-dom4j + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // Disable DTDs + factory.setXIncludeAware(false); // Disable XML Inclusions + + // from : + // https://community.veracode.com/s/article/Java-Remediation-Guidance-for-XXE + factory.setExpandEntityReferences(false); // disable expand entity reference nodes + + } catch (ParserConfigurationException e) { + throw new IllegalStateException("Unable to create DocumentBuilderFactory", e); + } + factory.setNamespaceAware(true); + return factory; + } + /** * Parse a DDF file. * diff --git a/leshan-core/src/main/java/org/eclipse/leshan/core/model/DefaultDDFFileValidator.java b/leshan-core/src/main/java/org/eclipse/leshan/core/model/DefaultDDFFileValidator.java index fa93f930d7..7352275ec2 100644 --- a/leshan-core/src/main/java/org/eclipse/leshan/core/model/DefaultDDFFileValidator.java +++ b/leshan-core/src/main/java/org/eclipse/leshan/core/model/DefaultDDFFileValidator.java @@ -30,6 +30,8 @@ import org.eclipse.leshan.core.util.Validate; import org.w3c.dom.Node; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; /** * A DDF File Validator. @@ -95,7 +97,30 @@ public void validate(Source xmlToValidate) throws SAXException, IOException { protected Schema getEmbeddedLwM2mSchema() throws SAXException { InputStream inputStream = DDFFileValidator.class.getResourceAsStream(schema); Source source = new StreamSource(inputStream); - SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + SchemaFactory schemaFactory = createSchemaFactory(); return schemaFactory.newSchema(source); } + + protected SchemaFactory createSchemaFactory() { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + try { + // Create Safe SchemaFactory (not vulnerable to XXE Attacks) + // -------------------------------------------------------- + // There is several recommendation from different source we try to apply all, even if some are maybe + // redundant. + + // from : + // https://semgrep.dev/docs/cheat-sheets/java-xxe/ + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + + // from : + // https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#schemafactory + factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); + factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); + + } catch (SAXNotRecognizedException | SAXNotSupportedException e) { + throw new IllegalStateException("Unable to create SchemaFactory", e); + } + return factory; + } }