File Upload Vulnerabilities: The Complete Practical Guide

Polyglots and Image-Parser Attacks

Advanced file upload attacks: a file that is a valid image and a valid script at once, SVG as a script carrier, ImageTragick parser bugs, and re-encoding.

Published

When a server does more than glance at the first bytes, when it actually parses or re-encodes your upload as an image, the simple tricks die. Polyglots and parser attacks are the answer. A polyglot is a single file that is a real image and a real script at once, and a parser attack targets the image library itself. These are the advanced rungs of the ladder, for when the easy bypasses are gone.

What a polyglot is

A polyglot is one file valid as two formats simultaneously. For uploads, the useful combination is a file that is a genuine, renderable image and also a working script. The image validity carries it past a check that opens and verifies the file as an image. The script is still in there for the server to run when it serves or includes the file as code. Unlike a plain magic-byte prefix, a polyglot is a real image, so it survives checks that actually parse it.

Building a GIF/PHP polyglot

The classic example is a file that is a valid GIF and a valid PHP script. A GIF starts with a signature and a header the parser reads, and you place PHP where it does not disturb the image structure:

GIF89a... (valid GIF header and image data) ... <?php system($_GET['c']); ?>

An image check opens it and sees a legitimate GIF. The PHP interpreter, if the file is executed, runs the code. The craft is in keeping both parsers happy at once, so the image renders and the script still runs.

SVG as an XML and script carrier

SVG is not a raster image, it is XML, which makes it a powerful carrier. If the server serves your SVG inline or parses it, the markup inside runs:

<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)"/>

An SVG served inline executes its script in the viewer's browser, which is stored XSS. The same XML can carry an external entity for XXE when the server parses it. SVG is the bridge between file upload and the client-side and parser attacks in non-RCE exploits.

ImageTragick-class parser bugs

Sometimes the vulnerability is in the image library, not your file's cleverness. ImageTragick (CVE-2016-3714) was a set of flaws in ImageMagick where crafted input abused the library's delegate handling to run commands during processing. The lesson generalizes: an image processor is a complex parser, and feeding it malicious input can trigger code execution, file reads, or SSRF inside the library itself, before any question of where the file is stored. Fingerprint the processing library and check it against known parser bugs.

When re-encoding kills the payload, and when it does not

Re-encoding, decoding the upload and re-saving it as a fresh image, is the defense that beats most of this. It discards appended bytes, metadata, and anything outside the pixel data, so a naive polyglot loses its code. But it is not absolute:

  • A payload hidden in image data that the re-encoder preserves can survive.
  • A parser bug that fires during the decode triggers before any re-save happens.
  • SVG and other markup formats are often not re-rasterized at all, so their script is untouched.

Work out exactly what the server does to the image, then choose a technique that outlives it.

Polyglots and parser attacks are where file upload gets genuinely advanced, and they pay off against the apps that thought re-encoding made them safe. Practice building a surviving payload on a free live target.

← Back to File Upload Vulnerabilities: The Complete Practical Guide