Last month I helped a friend debug why his eBay listings kept attracting local lowballers. He was selling camera gear, priced fairly, but kept getting “I can pick up today” messages from people 10 minutes away. He hadn’t listed his city anywhere.
Turns out every photo he uploaded contained GPS coordinates accurate to about 3 meters. His iPhone embedded them automatically, and eBay’s uploader didn’t strip them. His home address was in every listing photo.
What EXIF Data Actually Contains
EXIF (Exchangeable Image File Format) is metadata baked into JPEG and TIFF files by your camera or phone. Most people know about the basics — date taken, camera model. But here’s what a typical iPhone 15 photo includes:
GPS Latitude: 37.7749° N
GPS Longitude: 122.4194° W
GPS Altitude: 12.3m
Camera Model: iPhone 15 Pro Max
Lens: iPhone 15 Pro Max back triple camera 6.765mm f/1.78
Software: 17.4.1
Date/Time Original: 2026:04:15 14:23:07
Exposure Time: 1/120
ISO: 50
Focal Length: 6.765mm
Image Unique ID: 4A3B2C1D...
That’s your exact location, what phone you own, what OS version you’re running, and when you were there. Run exiftool on any photo from your phone and count the fields — I typically see 60-90 metadata entries per image.
Where This Gets Dangerous
Social media platforms handle this inconsistently. Instagram and Facebook strip EXIF on upload (they keep a copy server-side, naturally). But plenty of places don’t:
- eBay, Craigslist, Facebook Marketplace — listing photos often retain full EXIF
- WordPress (default) — uploaded images keep all metadata unless you configure a plugin
- Email attachments — always retain EXIF
- Slack, Discord — file uploads retain EXIF (Discord strips on CDN, Slack doesn’t)
- Personal blogs, forums — almost never strip metadata
I tested this across 15 platforms last year. Only 5 stripped EXIF on upload. The rest served the original file with full metadata intact.
The Technical Side: How EXIF Parsing Works
EXIF data sits in the APP1 marker segment of a JPEG file, starting at byte offset 2 (right after the SOI marker 0xFFD8). The structure follows TIFF formatting internally — it’s essentially a mini TIFF file embedded in your JPEG header.
JPEG Structure:
[FFD8] — Start of Image
[FFE1][length] — APP1 marker (EXIF lives here)
"Exif " — EXIF header (6 bytes)
[TIFF header] — byte order (II or MM), magic 42
[IFD0] — main image tags
[IFD1] — thumbnail tags
[GPS IFD] — latitude, longitude, altitude
[EXIF IFD] — camera settings, timestamps
[FFE0] — APP0 (JFIF, optional)
[FFC0/FFC2] — Start of Frame
[FFDA] — Start of Scan (actual image data)
[FFD9] — End of Image
Stripping EXIF means removing the APP1 segment entirely, or selectively zeroing out specific IFD entries. The first approach is simpler and smaller — you’re cutting maybe 10-50KB from the file. The second is useful if you want to keep non-identifying data like color profiles (which affect how the image renders).
Browser-Side Stripping With PixelStrip
I built PixelStrip specifically for this. It’s a single-page tool that strips EXIF metadata entirely in your browser — no upload, no server, no third party ever sees your files.
Why browser-only matters for a privacy tool: if you’re stripping metadata because you don’t want your location exposed, sending that file to a server first defeats the purpose. PixelStrip uses the Canvas API to re-render the image, which naturally drops all metadata since Canvas produces a clean pixel buffer with no EXIF baggage.
The approach is straightforward:
// Read the file
const img = new Image();
img.src = URL.createObjectURL(file);
// Draw to canvas (strips all metadata)
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// Export clean image
canvas.toBlob(blob => {
// blob has zero EXIF data
saveAs(blob, 'clean_' + file.name);
}, 'image/jpeg', 0.92);
The 0.92 quality parameter matters. At 1.0 you get lossless but the file is often larger than the original because Canvas encoding differs from camera JPEG encoders. At 0.92 you get visually identical output at roughly the same file size. I tested this across 200 photos from three different phones — at 0.92 quality, the average SSIM score was 0.997 (effectively imperceptible difference).
Command-Line Alternative: exiftool
If you prefer the terminal, exiftool by Phil Harvey is the gold standard. It’s a Perl script that’s been maintained since 2003:
# Strip ALL metadata
exiftool -all= photo.jpg
# Strip GPS only, keep camera info
exiftool -gps:all= photo.jpg
# Strip and process entire directory
exiftool -all= -r ./photos/
# Check what metadata exists
exiftool -G1 -s photo.jpg
exiftool is more precise — it can selectively strip specific tags, handle batch operations, and process RAW formats. I use it in CI pipelines to strip metadata from any user-uploaded images before they hit production storage. PixelStrip fills the gap when I’m on someone else’s machine, on mobile, or helping a non-technical person who isn’t going to install Perl.
A Simple Pre-Upload Habit
The fix is boring: strip metadata before uploading anything. I’ve built it into my workflow three ways:
- iOS Shortcut — I have a Share Sheet shortcut that strips EXIF and copies the clean image to clipboard. Takes 2 taps.
- Git pre-commit hook — runs
exiftool -all= -ron any staged .jpg/.png files. Never accidentally commit a geotagged screenshot again. - Quick one-off — PixelStrip in a browser tab for anything I’m posting to forums, Marketplace, or email.
Here’s a minimal git hook if you want the same protection:
#!/bin/bash
# .git/hooks/pre-commit
# Strip EXIF from staged images
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep -iE '\.(jpe?g|tiff?)$')
if [ -n "$STAGED" ]; then
echo "Stripping EXIF from staged images..."
echo "$STAGED" | xargs exiftool -all= -overwrite_original
echo "$STAGED" | xargs git add
fi
What About PNG and WebP?
PNGs use a different metadata format — tEXt, iTXt, and zTXt chunks instead of EXIF. They can still contain GPS data if the creating application writes it (some Android cameras save PNGs with location data in tEXt chunks). WebP supports both EXIF and XMP metadata in its RIFF container.
PixelStrip handles all three formats through the Canvas re-render approach, which is format-agnostic. The Canvas API doesn’t care what format went in — it always outputs clean pixels.
Stop Leaking Data You Didn’t Mean To Share
EXIF stripping isn’t paranoia — it’s basic hygiene, like not leaving your house keys in the door. Every photo you share publicly with GPS data is a pin on a map pointing to where you live, work, or hang out.
If you’re working with sensitive images in a dev context, consider adding exiftool to your build pipeline. For quick one-offs, PixelStrip runs entirely in your browser with zero server involvement.
For developers dealing with image uploads in production — here’s a solid HTTP reference book (affiliate link) that covers content-type handling and file processing patterns I still refer back to. And if you’re processing images at scale, a reliable NVMe SSD (affiliate link) makes batch exiftool operations across thousands of photos noticeably faster.
Want daily market intelligence delivered free? Join Alpha Signal on Telegram — free market analysis, zero spam.
📧 Get weekly insights on security, trading, and tech. No spam, unsubscribe anytime.
Leave a Reply