Unzureichende Kontrolle der Document Type Definition
Beschreibung
Unzureichende Kontrolle der Document Type Definition ist eine XML-Verarbeitungs-Schwachstelle, bei der Software Document Type Definition (DTD)-Referenzen nicht ordnungsgemäß einschränkt und Angreifern ermöglicht, beliebige DTDs anzugeben. DTDs definieren die Struktur und zulässigen Elemente von XML-Dokumenten und können Entity-Deklarationen enthalten. Wenn ein XML-Parser eine DTD verarbeitet, kann er versuchen, Dateien vom lokalen System oder von entfernten Standorten zu lesen oder einzubinden. Wenn Angreifer den DTD-Inhalt kontrollieren können, können sie sensible Ressourcen angeben, externe Anfragen auslösen oder Ressourcenerschöpfung verursachen. Diese Schwachstelle ist eng mit XML External Entity (XXE)-Angriffen verwandt und ist in der SOAP-Spezifikation explizit verboten.
Risiko
Diese Schwachstelle ermöglicht mehrere Angriffsvektoren. Angreifer können beliebige Dateien vom Server lesen, indem sie externe Entitäten definieren, die auf lokale Dateien wie /etc/passwd oder Konfigurationsdateien mit Anmeldedaten verweisen. Server-Side Request Forgery (SSRF) wird möglich, wenn DTDs externe URLs angeben, was Angreifern ermöglicht, interne Netzwerke zu sondieren oder mit internen Diensten zu interagieren. Denial of Service durch "Billion Laughs"-Angriffe verwendet rekursive Entity-Definitionen, um übermäßig viel Speicher oder CPU zu verbrauchen. In einigen Fällen können Angreifer möglicherweise Code ausführen, wenn die geparsten Daten die Anwendungslogik beeinflussen. Die Schwachstelle betrifft jede Anwendung, die XML aus nicht vertrauenswürdigen Quellen ohne ordnungsgemäße DTD-Einschränkungen verarbeitet.
Lösung
Deaktivieren Sie die DTD-Verarbeitung vollständig beim Parsen von nicht vertrauenswürdigem XML - dies ist die effektivste Abwehrmassnahme. Konfigurieren Sie in den meisten Sprachen den XML-Parser so, dass DTDs nicht zugelassen werden. Wenn DTDs erforderlich sind, deaktivieren Sie die externe Entity-Auflösung. Setzen Sie in Java Features wie "http://apache.org/xml/features/disallow-doctype-decl" auf true. Verwenden Sie in PHP libxml_disable_entity_loader(). Setzen Sie in .NET DtdProcessing auf Prohibit. Verwenden Sie Allowlists für alle externen Ressourcen, auf die zugegriffen werden muss. Validieren und bereinigen Sie XML-Eingaben vor der Verarbeitung. Erwägen Sie die Verwendung von JSON oder anderen Formaten, die keine Entity-Expansion unterstützen, wenn nicht vertrauenswürdige Eingaben verarbeitet werden. Wenden Sie das Prinzip der minimalen Privilegien auf den Parsing-Prozess an.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Vertraulichkeit Dateien oder Verzeichnisse lesen - Angreifer können beliebige Systemdateien durch externe Entity-Referenzen in bösartigen DTDs lesen. |
| Verfügbarkeit | Bereich: Verfügbarkeit Ressourcenverbrauch - Rekursive Entity-Referenzen in DTDs können übermäßigen CPU- oder Speicherverbrauch auslösen (Billion Laughs-Angriff). |
| Integrität, Vertraulichkeit, Verfügbarkeit | Bereich: Integrität, Vertraulichkeit, Verfügbarkeit Unerlaubten Code oder Befehle ausführen - DTDs können beliebige HTTP-Anfragen auslösen, die Server ausführen, wobei möglicherweise Server-Vertrauensbeziehungen ausgenutzt werden. |
Beispielcode
Anfälliger Code
// Anfällig: DTD-Verarbeitung standardmäßig aktiviert
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class VulnerableXMLParser {
public Document parseXML(InputStream xmlInput) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Anfällig: Standardeinstellungen erlauben DTD-Verarbeitung
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(xmlInput);
}
}
// Bösartiges XML, das die Schwachstelle ausnutzt:
/*
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>&xxe;</data>
*/
# Anfällig: etree erlaubt externe Entitäten in einigen Konfigurationen standardmäßig
from lxml import etree
def vulnerable_parse_xml(xml_string):
# Anfällig: Standard-Parser kann DTDs verarbeiten
parser = etree.XMLParser()
doc = etree.fromstring(xml_string.encode(), parser)
return doc
# Bösartiges XML:
# <?xml version="1.0"?>
# <!DOCTYPE foo [
# <!ENTITY xxe SYSTEM "file:///etc/passwd">
# ]>
# <root>&xxe;</root>
// Anfällig: Externe Entitäten aktiviert
<?php
function vulnerableParseXML($xmlString) {
// Anfällig: Externes Entity-Laden nicht deaktiviert
$doc = new DOMDocument();
$doc->loadXML($xmlString); // Verarbeitet DTDs standardmäßig
return $doc;
}
// Bösartiges XML könnte Dateien lesen:
// <!DOCTYPE foo [
// <!ENTITY xxe SYSTEM "file:///etc/passwd">
// ]>
// <root>&xxe;</root>
?>
Korrigierter Code
// Korrigiert: DTD-Verarbeitung vollständig deaktivieren
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class FixedXMLParser {
public Document parseXML(InputStream xmlInput) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Korrigiert: DTD-Verarbeitung deaktivieren
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// Zusätzliche Härtung
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(xmlInput);
}
}
# Korrigiert: Externe Entity-Auflösung deaktivieren
from lxml import etree
from defusedxml import ElementTree as DefusedET
def fixed_parse_xml_lxml(xml_string):
# Korrigiert: Parser konfigurieren, um Entitäten nicht zuzulassen
parser = etree.XMLParser(
resolve_entities=False,
no_network=True,
dtd_validation=False,
load_dtd=False
)
doc = etree.fromstring(xml_string.encode(), parser)
return doc
def fixed_parse_xml_defused(xml_string):
# Korrigiert: defusedxml-Bibliothek verwenden (empfohlen)
doc = DefusedET.fromstring(xml_string)
return doc
// Korrigiert: Externes Entity-Laden deaktivieren
<?php
function fixedParseXML($xmlString) {
// Korrigiert: Externes Entity-Laden deaktivieren
$previousValue = libxml_disable_entity_loader(true);
$doc = new DOMDocument();
$doc->loadXML($xmlString, LIBXML_NOENT | LIBXML_DTDLOAD | LIBXML_DTDATTR);
// Vorherige Einstellung wiederherstellen
libxml_disable_entity_loader($previousValue);
return $doc;
}
// Besser: XMLReader mit korrekten Einstellungen verwenden
function fixedParseXMLReader($xmlString) {
libxml_disable_entity_loader(true);
$reader = new XMLReader();
$reader->XML($xmlString);
// DTD-Verarbeitung deaktivieren
$reader->setParserProperty(XMLReader::LOADDTD, false);
$reader->setParserProperty(XMLReader::DEFAULTATTRS, false);
$reader->setParserProperty(XMLReader::VALIDATE, false);
$reader->setParserProperty(XMLReader::SUBST_ENTITIES, false);
// XML verarbeiten...
while ($reader->read()) {
// Knoten behandeln
}
}
?>
Verwandte CWEs
- CWE-706: Verwendung falsch aufgelöster Namen oder Referenzen (Eltern)
- CWE-829: Einbindung von Funktionalität aus nicht vertrauenswürdiger Kontrollsphäre (Eltern)
- CWE-776: Unzureichende Beschränkung rekursiver Entity-Referenzen in DTDs (kann vorangehen - Billion Laughs)
- CWE-611: Unzureichende Beschränkung von XML External Entity-Referenzen (verwandtes XXE)
- CWE-918: Server-Side Request Forgery (kann durch SSRF via DTD resultieren)
Referenzen
- MITRE Corporation. "CWE-827: Improper Control of Document Type Definition." https://cwe.mitre.org/data/definitions/827.html
- OWASP. "XML External Entity (XXE) Prevention Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
- OWASP. "Testing for XML Injection." https://owasp.org/www-project-web-security-testing-guide/