Deep Dives

EXIF Metadata: A Technical Guide to the Privacy Leak in Your Photos

koboshiCo-founder
·10 min read
EXIF Metadata: A Technical Guide to the Privacy Leak in Your Photos
Summary

Every photo from a phone or camera carries a second file inside it: shooting settings, timestamps, serial numbers, and often GPS coordinates. Here is the byte-level structure of EXIF, how to inspect it, how it exposes you, and how format conversion wipes it.

Take a photo on an iPhone and open the JPEG in a hex editor. A few hundred bytes past the FF D8 start marker, you find this:

FF E1 1C 24 45 78 69 66 00 00 4D 4D 00 2A 00 00 00 08

FF E1 is the APP1 segment marker. The two bytes after it are the segment length. Then six bytes spell Exif\0\0, and right behind them sits a TIFF header (4D 4D 00 2A means big-endian). Your JPEG is carrying a second, smaller file inside it, one that often reveals more about you than the image itself.

What EXIF Actually Is

EXIF stands for Exchangeable Image File Format. JEIDA (Japan Electronic Industry Development Association) published version 1.0 in 1995. JEITA and CIPA maintain the standard today; EXIF 3.0 arrived in 2023.

Structurally, EXIF is a TIFF. After the Exif\0\0 header comes a byte-order marker, then a chain of Image File Directories (IFDs). Every IFD entry is twelve bytes:

Bytes 0-1:   Tag ID (e.g. 0x010F = Make)
Bytes 2-3:   Data type (ASCII, rational, short, long)
Bytes 4-7:   Value count
Bytes 8-11:  Inline value, or an offset to it

Two subdirectories matter for privacy. The EXIF SubIFD (pointed to by tag 0x8769) holds camera settings, serial numbers, and timestamps. The GPS IFD (tag 0x8825) stores latitude and longitude as three rational numbers each: degrees, minutes, seconds.

There is usually a thumbnail stored in IFD1 as well, a small JPEG embedded in the metadata. Hold that thought; it matters later.

Which containers carry EXIF:

FormatEXIF locationNotes
JPEGAPP1 segmentWhere EXIF started
HEICExif item in the meta boxiPhone default since iOS 11
WebPEXIF chunk inside VP8XOptional, often absent
PNGeXIf chunkAdded to the spec in 2017
TIFFThe file itself is TIFFThe parent format of EXIF
BMP/ICONot supportedNo metadata structure at all

Why Cameras Started Writing It

The mid-90s problem was mundane and practical. Digital cameras produced files with zero context. Film photographers had negatives, lab envelopes with processing dates, and notes. Digital shooters had a directory full of DSC_0042.JPG files and nothing else.

EXIF solved three concrete needs:

  • Exposure records. Aperture, shutter speed, ISO, and focal length, so a photographer could review why a shot worked and repeat it.
  • Print ordering. DPOF (Digital Print Order Format) let you mark photos on the camera and have a kiosk print them later, using EXIF fields like rotation.
  • Orientation and preview. The Orientation tag keeps portrait shots upright, and the embedded thumbnail made camera LCD browsing fast.

Notice the assumption underneath all of this: photos stay with their owner. EXIF was designed for a world where a photo moved from CF card to hard drive to print kiosk. Nobody at JEIDA in 1995 was planning for a world where you upload a dozen photos a day to public servers.

What Is Actually Inside

Open any phone photo in a metadata reader and the tag list runs long. The fields that matter for privacy:

TagExample valueWhat it reveals
Make / ModelApple, iPhone 15 ProYour hardware
BodySerialNumber / LensSerialNumberUnique per deviceA fingerprint of your camera
DateTimeOriginal + OffsetTime2026:06:30 18:42:11 +09:00When, down to the second
GPSLatitude / GPSLongitude37°46'29" N, 122°25'10" WWhere, within meters
GPSAltitude14.2 mWhich floor, roughly
SoftwareInstagram, Photoshop 26.1What touched the file
Artist / CopyrightFree textSometimes a real name
IFD1 thumbnailA second JPEGA copy of the unedited image

exiftool output from a real iPhone photo, trimmed for brevity:

$ exiftool IMG_4021.HEIC
Make                            : Apple
Camera Model Name               : iPhone 15 Pro
Serial Number                   : F2LX8A1BCD
Date/Time Original              : 2026:06:30 18:42:11
GPS Latitude                    : 37 deg 46' 29.28" N
GPS Longitude                   : 122 deg 25' 10.41" W
GPS Altitude                    : 14.2 m Above Sea Level

Thirty seconds of reading, and a stranger knows what you shoot with, when you were there, and where "there" is, give or take a few meters.

How to Read It on Your Machine

Windows

Right-click the file, open Properties, go to the Details tab. Make, model, dates, and GPS coordinates are all listed there. The same tab has a "Remove Properties and Personal Information" link at the bottom, which opens a basic stripping dialog.

For raw access in PowerShell:

Add-Type -AssemblyName System.Drawing
$img = [System.Drawing.Image]::FromFile("C:\photos\IMG_4021.jpg")
$img.PropertyItems | ForEach-Object {
    $text = [System.Text.Encoding]::ASCII.GetString($_.Value).Trim([char]0)
    "Tag 0x{0:X4} (len {1}): {2}" -f $_.Id, $_.Len, $text
}
$img.Dispose()

Numeric fields come out as raw bytes, but ASCII tags like Make and Software print cleanly.

macOS

Open the image in Preview, then Tools, Show Inspector, and check the EXIF and GPS tabs. The GPS tab even renders a map pin.

From the terminal, mdls lists everything Spotlight indexed:

mdls IMG_4021.jpg | grep -iE "gps|latitude|longitude|model"

Or install ExifTool with brew install exiftool for the full tag list.

Linux

ExifTool is the standard:

exiftool IMG_4021.jpg

Lighter alternatives: exiv2 IMG_4021.jpg, or ImageMagick's identify -verbose IMG_4021.jpg | grep -i exif.

From a Browser, With Twenty Lines of TypeScript

Finding the APP1 segment yourself takes a loop over the JPEG marker chain:

async function findExifSegment(file: File): Promise<number> {
  const bytes = new Uint8Array(await file.slice(0, 128 * 1024).arrayBuffer())
  if (bytes[0] !== 0xff || bytes[1] !== 0xd8) return -1 // not a JPEG

  let offset = 2
  while (offset < bytes.length - 12) {
    if (bytes[offset] !== 0xff) break
    const marker = bytes[offset + 1]
    const length = (bytes[offset + 2] << 8) | bytes[offset + 3]
    if (
      marker === 0xe1 &&
      String.fromCharCode(...bytes.slice(offset + 4, offset + 10)) ===
        "Exif\0\0"
    ) {
      return offset
    }
    offset += 2 + length
  }
  return -1
}

How EXIF Leaks Your Privacy

GPS Coordinates Give Away Your Location

Phones record GPS whenever the camera app has location permission, which is the default most people tap through once and forget. Post a photo of your balcony, your desk, or your kid's school project to a forum or a marketplace listing, and you have published your address with meter-level precision.

The famous case is John McAfee. In December 2012 he was on the run and hiding in Guatemala. Vice published a photo of him taken on an iPhone 4S, and the EXIF data held full GPS coordinates. Anyone could read exactly where in Guatemala he was. Days later he was in Guatemalan custody.

BodySerialNumber and LensSerialNumber are unique per device. Two anonymous accounts posting photos shot on the same camera can be linked with near certainty. Researchers have crawled photo sites to cluster images by camera serial for exactly this reason. You can keep your identities separate online. Your camera makes no such distinction.

Timestamps Sketch Your Routine

DateTimeOriginal, plus the timezone offset. On its own one timestamp says little, but a year of uploads shows when you wake up, when you leave home, and when you travel.

The Thumbnail Gives You Away

The IFD1 thumbnail is a separate JPEG inside the metadata. Crop a face or a document out of the main image, and plenty of editors leave the original thumbnail untouched. Whoever extracts it gets the uncropped photo. In 2003 a TechTV host posted cropped photos of herself, and readers recovered the full frames from the EXIF thumbnails. The lesson has stuck around because tools keep making the same mistake.

Where EXIF Survives the Upload

The big social platforms (Facebook, Instagram, X) strip EXIF from images at upload. Everything else mostly does not: email attachments, forum uploads, marketplace listings, cloud drive share links, AirDrop, and any messenger set to send original quality. If the file leaves your device unchanged, the metadata leaves with it.

What Happens When You Convert Formats

Converting a photo is not automatically stripping it. Converters come in two kinds:

  1. Metadata copiers. Tools that re-encode but deliberately carry the tags across: ExifTool, ffmpeg, and most GUI converters with a "keep metadata" default. Run JPEG to WebP through a copier and your GPS coordinates move into the WebP EXIF chunk untouched.
  2. Pixel re-encoders. Tools that decode to raw pixels and encode a brand new file from them. The output contains image data only, because the metadata was never part of the pixels.

Stripping by hand is one command either way:

# ExifTool: wipe every tag, keep the image
exiftool -all= -overwrite_original photo.jpg

# ImageMagick 7: re-encode without metadata
magick photo.jpg -strip photo-clean.jpg

One detail needs care here: orientation. EXIF Orientation (tag 0x0112) tells viewers to rotate the image, often by 90 degrees. Strip the tags without baking that rotation into the pixels, and every portrait photo comes out sideways. The correct order is decode with orientation applied, then drop the metadata. A tool that strips without rotating is worse than no stripping at all.

What Our Converters Do With EXIF

Every converter on this site is a pixel re-encoder. The pipeline is identical across all of them:

  1. Decode the source file to raw pixels in your browser (a WebAssembly build of libheif for HEIC, the native browser decoder for the rest).
  2. Draw the pixels to a canvas, with EXIF orientation already applied during decode.
  3. Encode the canvas into the target format.

The output file holds compressed pixels and nothing else. No APP1 segment, no EXIF or eXIf chunk, no GPS IFD, no serial numbers, no embedded thumbnail. There is no code path that copies metadata, because there is no metadata in memory to copy. And since the whole thing runs client-side, the file never leaves your device, so no server ever sees the original either.

Pick your source format:

Drop a file in, download the converted copy, share that instead. The pixels are identical; the metadata is gone.

The Short Version

  • Before you share a photo anywhere EXIF survives (email, forums, marketplaces, direct links), check it first. Properties on Windows, Inspector on macOS, exiftool on Linux.
  • If the file carries GPS data and you would rather it did not, convert it. Every tool linked above outputs pixels only.
  • If you post under separate identities, camera serial numbers can link them. Stripping handles that too.
  • Keep your originals untouched. EXIF is genuinely useful inside your own archive. The copies you publish are the ones that should be clean.

More blog posts to read