Reject Image Polyglots After EXIF Removal, Before They Reach Your CDN
The Problem with EXIF-Only Checks
Removing EXIF GPS protects one privacy boundary. It does not prove that an uploaded JPEG contains only a JPEG. A useful hostile fixture is a valid image followed by bytes for another format. Many decoders stop at JPEGโs end marker and display the picture successfully, while downstream scanners, content sniffers, or accidental downloads may interpret the trailing payload differently.
Testing with a Fixture Set
Build a fixture set rather than trusting extensions:
clean.jpg- valid JPEGexif-gps.jpg- valid JPEG with locationjpeg-plus-zip.jpg- JPEG followed by ZIP bytesjpeg-plus-html.jpg- JPEG followed by HTMLtruncated.jpg- missing end markeroversized-dimensions.jpg- small file, dangerous decode cost
Recommended Upload Pipeline
My upload gate has independent layers:
- Store the original in a non-public quarantine location.
- Enforce byte-size and decoded-dimension limits.
- Decode with a maintained image library.
- Re-encode pixels into a new file, discarding metadata and trailing bytes.
- Verify the outputโs signature, dimensions, and complete parse.
- Publish only the derived object under a server-generated name.
Boundary Checks and Re-encoding
A boundary check can detect bytes after the end marker, but re-encoding is the stronger transformation because it creates a new representation from decoded pixels. Keep the original inaccessible and delete it according to a tested lifecycle.
Verification Assertions
assert(outputSize <= limit);
assert(decoded.width * decoded.height <= pixelBudget);
assert(parseConsumesEntireFile(output));
assert(noLocationMetadata(output));
Defense in Depth
The OWASP File Upload Cheat Sheet recommends defense in depth: allowlisted types, generated filenames, size limits, storage separation, and content validation. No single MIME header or metadata scrubber replaces that chain. The important privacy lesson is broader than EXIF: inspect every representation that survives the upload pipeline, and publish only a constrained derivative.
Comments
No comments yet. Start the discussion.