XML Entity Expansion in Go Lang
Vulnerable example
The Go snippet below parses the content of an uploaded XML file using the libxml2
library (error handling has been omitted for brevity):
// open the form file
file, err := c.FormFile("xml")
xml, err := file.Open()
defer xml.Close()
// parse the XML body
p := parser.New(parser.XMLParseNoEnt)
doc, err := p.ParseReader(xml)
defer doc.Free()
// use the XML document and return data to the user...
When p.ParseReader(xml)
is invoked, it parses and expands the external entities, for example, when uploading the following XML document:
<!DOCTYPE d [<!ENTITY e SYSTEM "file:///etc/passwd">]><t>&e;</t>
The entity &e;
is expanded with the content of the local /etc/passwd
system file, resulting in the disclosure of the file.
Prevention
Even though Go ships with a native XML parser (encoding/xml
) that can be used for mere XML data parsing and manipulation, it does not support advanced XML features like validation. Developers that use the native XML solution should not usually concern themselves with any security aspects. If a parser with more features is required, then developers must rely on third-parties libraries, for example https://github.com/lestrrat-go/libxml2.
Parsing of external entities is disabled by default, and care must be taken to avoid processing untrusted XML data when this option is enabled. Parsing of external entities can be enabled as follows:
p := parser.New(parser.XMLParseNoEnt)
References
OWASP - XML External Entity (XXE) Processing OWASP - XML External Entity Prevention Cheat Sheet