Xml External Entities in Cockroachdb
How Xml External Entities Manifests in CockroachDB
CockroachDB itself does not provide an XML data type or native XML parsing functions, so an XXE vulnerability cannot be triggered directly inside the database. However, many applications that use CockroachDB as their backend accept XML payloads from clients, parse that XML to extract values, and then store those values in CockroachDB tables via its PostgreSQL‑compatible wire protocol. If the XML parser is configured to resolve external entities, an attacker can inject a DOCTYPE that points to a local file or an internal service, causing the parser to disclose file contents or make out‑of‑band requests before the application ever touches the database.
Consider a typical Java‑based service that exposes a POST /users endpoint expecting an XML body like:
<user>
<id>123</id>
<name>Alice</name>
</user>
The handler might use the standard JDK DocumentBuilder to parse the payload, extract the <id> value, and then insert it into a CockroachDB table with a PreparedStatement:
@PostMapping("/users")
public ResponseEntity<Void> createUser(@RequestBody String xml) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(xml)));
String id = doc.getElementsByTagName("id").item(0).getTextContent();
String name = doc.getElementsByTagName("name").item(0).getTextContent();
try (Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:26257/defaultdb");
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO users (id, name) VALUES (?, ?)")) {
ps.setString(1, id);
ps.setString(2, name);
ps.executeUpdate();
}
return ResponseEntity.ok().build();
}
If an attacker sends the following XML, the parser will attempt to resolve the external entity:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root>
<id>&xxe;</id>
<name>attacker</name>
</root>
The DocumentBuilder will expand &xxe; to the contents of /etc/passwd, which is then inserted into the users.id column. Depending on how the application later displays or logs that column, the file contents may be leaked. Similarly, pointing the entity at an internal service (e.g., http://169.254.169.254/latest/meta-data/) can lead to SSRF against the host running the application.
Because CockroachDB only receives the already‑expanded string, the database itself shows no anomalous behavior; the vulnerability lives entirely in the XML parsing layer that precedes the database interaction.
Cockroachdb-Specific Detection
Detecting XXE in a CockroachDB‑backed service requires focusing on the input handling code rather than the database. Manual code review should look for uses of javax.xml.parsers.DocumentBuilderFactory, SAXParserFactory, or any XML‑binding libraries (JAXB, Woodstox) where external entity resolution is not explicitly disabled.
Automated scanners can help by sending crafted XML payloads to the HTTP endpoint and observing the response. middleBrick’s Input Validation check includes a set of XXE probes:
- It submits an XML body containing an external entity that references a known file (e.g.,
file:///etc/hostname). - It measures whether the response contains unexpected data (indicating successful entity expansion) or whether the request triggers an out‑of‑band interaction (if the entity points to a remote server the scanner controls).
- Because the scanner works unauthenticated and only needs the public URL, it can be run against staging or production endpoints without any credentials or agents.
- If the endpoint returns a 200 OK with the injected value reflected in the response body, or if the scanner detects a DNS/HTTP callback to its monitoring server, the finding is reported with severity high and includes the exact payload that triggered the issue.
For CockroachDB‑specific contexts, the scanner also checks whether the reflected value later appears in database‑related error messages or logs (e.g., a SQL error that includes the expanded entity). This helps distinguish a benign XML echo from a true XXE that could affect data stored in CockroachDB.
Running middleBrick is as simple as:
middlebrick scan https://api.example.com/users
The output will list the Input Validation check, flag any XXE findings, and provide remediation guidance.
Cockroachdb-Specific Remediation
The fix is to prevent the XML parser from resolving external entities before the data is handed off to CockroachDB. This does not require any changes to the database driver or schema; it is purely an application‑level hardening step.
In Java, the recommended approach is to disable DTD processing and external entity resolution on the DocumentBuilderFactory (or the equivalent SAX parser). The following snippet shows a safe implementation:
private DocumentBuilder createSafeBuilder() throws ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// Disallow DTDs completely
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// If you absolutely need DTDs but not external entities:
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// Disable external DTD loading (Xerces specific)
dbf.setAttribute("http://apache.org/xml/properties/security-manager",
new org.apache.xerces.util.SecurityManager());
return dbf.newDocumentBuilder();
}
@PostMapping("/users")
public ResponseEntity<Void> createUser(@RequestBody String xml) throws Exception {
DocumentBuilder db = createSafeBuilder();
Document doc = db.parse(new InputSource(new StringReader(xml)));
// ... extract values and use PreparedStatement as before
}
If you are using a higher‑level library such as JAXB, set the property:
Map<String, Object> jaxbProps = new HashMap<>();
jaxbProps.put(JAXBProperties.SECURITY_MANAGER, new SecurityManager());
jaxbContext.createUnmarshaller().setProperties(jaxbProps);
For .NET applications using XmlReader, configure the XmlReaderSettings:
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit; // or Ignore if DTDs are needed
settings.XmlResolver = null; // blocks external resolution
using (XmlReader reader = XmlReader.Create(new StringReader(xml), settings)) {
// parse safely
}
After the XML is safely parsed and the values extracted, continue to use CockroachDB’s standard PreparedStatement or ORM methods to insert the data. This preserves the defense‑in‑depth principle: the XML layer cannot inject malicious content, and the database layer protects against SQL injection.
Finally, consider adding a schema validation step (e.g., XSD) that rejects any DOCTYPE declarations outright. By combining parser hardening with strict input validation, you eliminate the XXE vector that could otherwise lead to data leakage, SSRF, or unintended interactions with services that your CockroachDB instance might be able to reach.