Mitigating XXE in SVG Image Parsers
Scalable Vector Graphics (SVG) are XML-based image files that allow rich, scalable vector visuals, but their underlying XML structure exposes server-side applications to XML External Entity (XXE) injection vulnerabilities. When an application processes user-uploaded SVGs without proper safeguards, attackers can define custom XML entities to read local files, execute Server-Side Request Forgery (SSRF), or cause Denial of Service (DoS). This article outlines how server-side image processing libraries and parsers defend against XXE attacks through parser reconfiguration, entity restriction, sanitization, and sandboxed rendering.
Why SVGs Are Vulnerable to XXE
Unlike binary image formats like JPEG or PNG, an SVG file is plain XML text. Default XML parser configurations often support features such as Document Type Definitions (DTDs) and external entity resolution:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg xmlns="http://www.w3.org/2000/svg">
<text>&xxe;</text>
</svg>If a server-side parser (such as ImageMagick, Batik, or libxml-based
tools) attempts to render or extract metadata from this file, it may
resolve the entity &xxe; and expose sensitive server
contents or initiate unauthorized outbound network requests.
Key Mitigation Strategies
1. Disabling Document Type Definitions (DTDs)
The most effective way to eliminate XXE vulnerabilities is to completely disable DTD parsing in the underlying XML engine. Since valid, modern SVGs rarely require custom DTDs for styling or rendering, turning off DTD processing completely removes the parsing mechanism attackers exploit.
- Java (DOM/SAX/Batik): Set
http://apache.org/xml/features/disallow-doctype-decltotrue. - Python (
defusedxml/lxml): Usedefusedxml, which automatically forbids DTDs and external entities, or setresolve_entities=Falseandload_dtd=Falseinlxml. - C/C++ (
libxml2): Avoid setting theXML_PARSE_NOENTflag, as it expands entities by default, and ensureXML_PARSE_DTDLOADis disabled.
2. Disabling External Entity Resolution
If DTDs cannot be disabled entirely, parsers must be configured to prohibit external entity fetching and parameter entities:
- Set
external-general-entitiesandexternal-parameter-entitiesfeature flags tofalse. - Enable the
XML_PARSE_NONEToption inlibxml2-based parsers to block any network access during XML parsing, preventing SSRF attacks via remote URLs inSYSTEMidentifiers. - Set a custom entity resolver that returns an empty stream or throws an exception whenever an external resource is requested.
3. Using Safe Parsing Wrappers
Standard image libraries often delegate XML parsing to underlying system packages. Hardening requires using secure library wrappers or configurations:
- Python: Replace standard
xml.etreeor unsafelxmlimplementations with thedefusedxmlpackage when parsing untrusted SVG uploads. - Node.js: When using libraries like
sharporlibrsvg, ensure underlying dependencies are updated to versions that disable entity expansion by default. - ImageMagick: Update
policy.xmlto restrict or disable vulnerable coders (MVG,MSVG, orHTTPSdelegates) and enforce strict resource limits to counter XML entity expansion (Billion Laughs) attacks.
4. Input Sanitization
Before passing an SVG to an image parser or rasterizer, sanitize the raw XML payload to strip dangerous elements and attributes:
- Remove all
<!DOCTYPE>declarations and<!ENTITY>tags using regular expressions or specialized sanitizers (e.g.,DOMPurifywith SVG profiles orsvg-sanitizer). - Strip interactive or scriptable elements such as
<script>,onload, and<foreignObject>tags to prevent Cross-Site Scripting (XSS) if the SVG is served back to end-users.
5. Rasterization and Sandboxing
When user-uploaded SVGs must be converted to raster images (like PNG or JPEG) for storage or display:
- Isolated Execution: Run conversion utilities (such as headless Chrome or Inkscape) in an isolated container or restricted execution context with no network access and read-only filesystem privileges.
- Resource Limits: Implement strict memory and CPU limits to mitigate DoS attacks caused by nested entity loops (Billion Laughs) or recursive XML payloads.