Note
web
php
libmagic
file-upload
mime-confusion
xss
json
Defeat finfo/libmagic upload checks with deeply nested JSON whose leading bytes look like an allowed image, then have the client parse it as JSON.
libmagic Confusion with Deep JSON / SVG
libmagic uses heuristics and may fail to classify very deep JSON as JSON. If early bytes resemble SVG
or another allowed image format, the upload check accepts it — even though the client later parses it as
JSON. This is cross-layer type confusion: the server blesses it as image content, while the frontend
ignores response MIME and treats it as JSON because the code told it to.
Why It Works
- Validation trusts content sniffing; the frontend trusts its own code path. The same bytes satisfy both loosely enough to bridge the trust boundaries.
Vulnerable Pattern
- PHP upload validation based on
finfo/libmagic, followed by a frontend (e.g. Angular) that fetches the same resource as JSON by code path rather than by MIME.
Exploit Flow
- Confirm the frontend really parses by expected type in code, not by
Content-Type. - Generate syntactically valid but deeply nested JSON that pushes
libmagicaway from recognizing JSON. - Embed HTML in a field the frontend later trusts into
[innerHTML]or an equivalent sink.
Variations
- SVG-like leading bytes, alternative image markers, or other structured formats where server and client disagree.
Common Blockers
- Server re-encodes uploads, client performs schema validation, or the upload route recomputes MIME from extension instead of content.
PoC Sketch
# payload.json: 500+ nested objects + "content":"<img src=x onerror=alert(1)>"
# make the first bytes look SVG-like enough for libmagic
Good Situations To Use It
- Upload validation is content-sniffing based.
- The frontend fetches the file as JSON regardless of MIME.
- A JSON field ends up in a trusted-HTML sink.
Sources
fcsc2026/web/deep_blue