pwneglyph logo
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

  1. Confirm the frontend really parses by expected type in code, not by Content-Type.
  2. Generate syntactically valid but deeply nested JSON that pushes libmagic away from recognizing JSON.
  3. 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