Test files › Images › svg-external-entity.svg
SVG with an external entity (XXE test)
SVG with a DOCTYPE declaring an external entity pointing at a local file path.
↓ Download svg-external-entity.svg| Filename | svg-external-entity.svg |
| Format | SVG |
| Size | 273 bytes (273 bytes) |
| MIME type | image/svg+xml |
| SHA-256 | 34cb8313af9e13289866d0db78d8173e91532750a8886345e6e637beefa0b53f |
What this file catchesSVG rasterisers backed by a full XML parser with entity resolution left on - a file-disclosure path (XXE) that image-processing code rarely gets audited for.
Handle it in code
Each snippet below was run against this exact file with Python 3.14.4 and Node 24.15.0 when this page was built, and the output shown is what it printed.
Python
An SVG is a document that can run script, so an uploaded one is an XSS risk when served inline. This screen is triage, not a sanitiser: serve user SVGs from a separate domain with a strict Content-Security-Policy, or rasterise them.
import re
RISKS = [
(r"<!ENTITY|<!DOCTYPE[^>]*\[", "declares entities (XXE)"),
(r"<script\b", "contains <script>"),
(r"\son[a-z]+\s*=", "has an on* event handler"),
(r"(?:href|src)\s*=\s*[\"']?\s*javascript:", "links to javascript:"),
(r"<foreignObject\b", "embeds HTML in foreignObject"),
(r"(?:href|src)\s*=\s*[\"']?\s*https?://", "loads an external resource"),
]
with open("svg-external-entity.svg", encoding="utf-8") as f:
svg = f.read()
found = [label for pattern, label in RISKS if re.search(pattern, svg, re.I)]
print("unsafe to serve inline: " + ", ".join(found) if found else "no active content found")Run against this file, it prints: unsafe to serve inline: declares entities (XXE)
Related guides and tools
Sample image filesFile signaturesMIME typesUpload validation checklistCheck a file's real typeVerify its SHA-256
Download & verify
curl -fsSL -o "svg-external-entity.svg" "https://files.hexaqa.com/image/svg-external-entity.svg"
curl -fsSL "https://files.hexaqa.com/image/svg-external-entity.svg" | sha256sum
# expect: 34cb8313af9e13289866d0db78d8173e91532750a8886345e6e637beefa0b53f