How Attackers Hide JavaScript in JPEG Comments

Attackers frequently exploit the binary structure of image formats to hide malicious JavaScript inside JPEG comment markers, creating structurally valid images that double as payload carriers. This technique leverages the COM marker defined by the JPEG specification to store arbitrary text without breaking the visual integrity of the graphic. While image tags do not execute this code natively, attackers chain this stealthy injection method with secondary vulnerabilities—such as polyglot execution, cross-site scripting (XSS), or metadata-parsing flaws—to achieve client-side code execution.

The Structure of the JPEG COM Marker

JPEG files consist of a sequence of segments, each beginning with a two-byte marker starting with 0xFF. The comment marker, designated as COM, uses the byte sequence 0xFF 0xFE.

Immediately following the 0xFF 0xFE marker is a two-byte value specifying the length of the comment payload (including the two bytes of the length field itself). Following the length indicator, the JPEG standard allows arbitrary binary or ASCII data up to 65,535 bytes. Image decoders parse this segment, recognize the length, and safely skip over the content to continue rendering the visual image data.

The Embedding Process

To inject a payload into the comment field, an attacker carries out a sequence of binary modifications:

  1. Locating or Appending the Marker: An attacker opens a valid JPEG file using a hex editor or an automated script (such as a Python script utilizing struct). They search for an existing 0xFF 0xFE sequence or identify the Start of Image marker (0xFF 0xD8) to insert a new comment block immediately after it.
  2. Calculating Segment Length: The attacker determines the byte length of their JavaScript payload, adds two bytes to account for the length field itself, and converts this value into a two-byte, big-endian integer.
  3. Injecting the Payload: The attacker writes the 0xFF 0xFE marker, inserts the calculated length bytes, and appends the raw JavaScript code (for example: /* */=alert(1);).
  4. Finalizing the File: The rest of the image data remains untouched. Because the image rendering engine only looks for visual markers (such as Start of Scan, 0xFF 0xDA), the embedded script does not trigger parsing errors or corrupt the visual output.

Execution Mechanisms

Placing JavaScript inside a JPEG does not automatically trigger execution when loaded via standard <img src="image.jpg"> tags. Attackers rely on specific delivery contexts to run the payload:

Mitigation Strategies

Defending against malicious metadata embedding requires proactive image sanitization and strict HTTP header enforcement: