Link Search Menu Expand Document

XML Entity Expansion in Ruby

Vulnerable example

Consider the following vulnerable Ruby on Rails example, which uses the Nokogiri library to parse the XML. Assume there is a builder in the background forming the XML response from the @response variable.

@response = Nokogiri::XML(request.body) do |config|
   config.strict.noent
end

The way in which the parser is configured introduces an XML Entity Expansion vulnerability, which can be exploited by sending a specially crafted XML document to expose arbitrary files; for example, /etc/passwd.

<!DOCTYPE doc [ <!ELEMENT elem ANY><!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<element>Legitimate Data&xxe;</element>

Note the above example inserts the xxe entity within the element. In some use cases, an XML response will use elements from the request; therefore, it is insufficient to solely filter out unwanted elements.

Prevention

The noent option configures Nokogiri to expand entities, introducing the vulnerability. In many XML parsing libraries, including Nokogiri, the default is to not do so. However, they may be configured to expand entities, such as in the example above with the noent option.

To remediate this, it is best to explicitly disable entity expansion; defaults may change.

The fixed code below parses XML safely by disabling entity expansion with the nonoent option.

@response = Nokogiri::XML(request.body) do |config|
   config.strict.nonoent
end

References

OWASP - XML External Entity (XXE) Processing OWASP - XML External Entity Prevention Cheat Sheet