DEV Community

Serguey Asael Shinder
Serguey Asael Shinder

Posted on

Your XML Parser Opened a File Because the Document Asked It To

The feature was an import.

Suppliers upload a product feed
as XML,
and the screen shows a preview.

Name.
Price.
Description.

A tester sent a feed
with four extra lines at the top.

The preview came back
and the description field
held the contents
of a configuration file
from the server's disk.

Nobody had written code
to read that file.

The parser did it,
because the document asked.

XML has a part
most of us never use on purpose.

The document type declaration.

It can define entities,
named pieces of text,
and an entity can be external,
which means its text lives
somewhere else.

At a file path.

At a URL.

So the feed declared an entity
pointing at a file on the server,
then used that entity
inside the description.

The parser did what the standard says.

It went and fetched the text
and put it in place.

Then your code
showed the description,
as it always does.

That is XXE,
an XML external entity attack.

It is old,
and it is still on the OWASP lists
because the defaults keep it alive.

In Java,
the standard DocumentBuilderFactory
resolves external entities
unless you tell it not to.

Use the same trick
with a URL inside the entity,
and your server
makes requests for the attacker,
from inside your network.

It is not only feeds.

An SVG is XML.

A Word document is a zip of XML.

A SAML response is XML.

Anywhere you parse a document
someone else wrote,
the document gets a say
in what your parser does.

So take the say away.

Turn off document type declarations
entirely,
the disallow doctype feature in Java,
which is what the OWASP cheat sheet
recommends first.

If you really need them,
turn off external entities
and external DTD loading,
one setting at a time,
and test each one.

Put the safe factory
in one helper,
and make it the only way
the codebase builds a parser.

Then write the test
with the four extra lines
and keep it forever.

The parser was not broken.

It was obedient.

To whoever wrote the file.

– Serguey Asael Shinder

Top comments (0)