XXE (XML External Entity) is a server-side parsing flaw. Your React app can trigger it whenever users upload or send XML to an API that parses XML insecurely. Here’s how it happens—and how to stop it.
How XXE sneaks into a React workflow
- React UI accepts XML (file upload/text).
- Frontend posts it to an API.
- Backend XML parser expands external entities (e.g.,
file://
,http://
). - Result: data exfiltration (e.g.,
/etc/passwd
), SSRF, or parser crashes.
👉 Read more AppSec posts on our blog: https://www.pentesttesting.com/blog/
Minimal React uploader (safe UX hints)
Use client checks for UX, but remember security lives on the server.
// React: accept only XML and reject DOCTYPE early (UX, not a guarantee)
function XmlUpload() {
const onFile = async (e) => {
const f = e.target.files?.[0];
if (!f) return;
if (!/(text|application)\/xml/.test(f.type)) return alert("XML only");
const text = await f.text();
if (/\<\!DOCTYPE/i.test(text)) return alert("DOCTYPE not allowed");
await fetch("/api/parse-xml", { method: "POST", body: text, headers:{ "Content-Type":"application/xml" }});
alert("Uploaded");
};
return <input type="file" accept=".xml" onChange={onFile} />;
}
Screenshot of our Free Website Vulnerability Scanner
Screenshot of the free tools webpage where you can access security assessment tools.
Example XXE payload (for understanding)
<?xml version="1.0"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///etc/hosts">
]>
<data>&xxe;</data>
Vulnerable Node.js pattern (don’t do this)
// Express + libxmljs2 with dangerous options
import express from "express";
import libxml from "libxmljs2";
const app = express();
app.post("/api/parse-xml", express.text({ type: "application/xml" }), (req, res) => {
// ❌ NOENT=true substitutes entities; DTD allowed
const doc = libxml.parseXml(req.body, { noent: true, dtdload: true, nonet: false });
res.json({ root: doc.root()?.name() });
});
app.listen(3000);
Secure Node.js parsing (do this instead)
// Disallow DTD + entity expansion + network
import express from "express";
import libxml from "libxmljs2";
const app = express();
app.post("/api/parse-xml", express.text({ type: "application/xml", limit: "200kb" }), (req, res) => {
if (/\<\!DOCTYPE/i.test(req.body)) return res.status(400).send("DOCTYPE not allowed"); // defense-in-depth
const doc = libxml.parseXml(req.body, { noent: false, dtdload: false, dtdvalid: false, nonet: true, noblanks: true, recover: true });
// ...safe extraction here
res.json({ ok: true });
});
app.listen(3000);
Alternative: use a non-DTD parser
// fast-xml-parser: does not resolve external entities
import { XMLParser } from "fast-xml-parser";
const parser = new XMLParser({ ignoreAttributes:false, allowBooleanAttributes:true });
const data = parser.parse(xmlString); // no external entity expansion
Harden your pipeline (checklist)
- Block
DOCTYPE
and external entities server-side. - Prefer parsers that don’t support DTD/XXE.
- Enforce strict
Content-Type
and size limits. - Run the API in a network-restricted environment (no egress by default).
- Add SAST/DAST to CI; include XXE tests.
Sample Assessment report by our free tool to check Website Vulnerability
Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.
Try it free
Scan your site with our Free Website Vulnerability Scanner: https://free.pentesttesting.com/
It flags common web risks and gives remediation tips you can act on today.
Related services (quick help from our team)
Managed IT Services
Stability + security from the ground up. https://www.pentesttesting.com/managed-it-services/
AI Application Cybersecurity
Secure LLMs, agents, and data pipelines. https://www.pentesttesting.com/ai-application-cybersecurity/
Offer Cybersecurity to Your Clients
White-label audits and scanners for agencies/MSPs. https://www.pentesttesting.com/offer-cybersecurity-service-to-your-client/
Stay updated: Subscribe on LinkedIn https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7327563980778995713
Top comments (0)