Strip Your Geotags, People!

It never ceases to amaze me how information-leaky our smartphone cameras are.

Even after editing pictures, it's a good idea to strip metadata from uploaded images, especially if they show where you live down to a city block.

Maybe GPS tags should be opt-in rather than opt-out.


This image of my chicken dinner had my home address in it, not really what I want to share.

In this case, GPS location metadata made it through GIMP using the default Export options, which will preserve all of the incoming metadata and pass it through.

This includes the following fields:

Exif.Image.GPSTag                            Long        1
Exif.GPSInfo.GPSVersionID                    Byte        4
Exif.GPSInfo.GPSLatitudeRef                  Ascii       2
Exif.GPSInfo.GPSLatitude                     Rational    3
Exif.GPSInfo.GPSLongitudeRef                 Ascii       2
Exif.GPSInfo.GPSLongitude                    Rational    3
Exif.GPSInfo.GPSAltitudeRef                  Byte        1
Exif.GPSInfo.GPSAltitude                     Rational    1
Exif.GPSInfo.GPSTimeStamp                    Rational    3
Exif.GPSInfo.GPSDOP                          Rational    1
Exif.GPSInfo.GPSImgDirectionRef              Ascii       2
Exif.GPSInfo.GPSImgDirection                 Rational    1
Exif.GPSInfo.GPSProcessingMethod             Undefined  13
Exif.GPSInfo.GPSDateStamp                    Ascii      11

Use exiv2 or something similar to remove these tags when pushing images to production, it's actually stupidly easy.

The commands exiv2 rm *.jpg and exiv2 rm *.png --- are pretty much all you need to know to remove all metadata from all of these files in one folder at once.

Doublecheck with exiv2 -pa pr *.jpg:


All clean.

If you're using GIMP to edit pictures and export them out to JPEG or PNG, make sure to uncheck the Save (EXIF, XMP) data fields when exporting, unless you're sure you need them.

You're good to go.

Update: Here's a script to do this for you for all images recursively in a folder, as well as add Creator + Copyright data and a hash to the image in case you're interested in seeing where it might get reposted.

#!/bin/bash
# Do not use -e here, since exiv2 will error out when DateTimeOriginal mising for -T.
set -uo pipefail
IFS=$'\n\t'

# Refs:
# https://exiv2.org/sample.html#modify
# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
# https://linuxize.com/post/bash-check-if-file-exists/
# https://iptc.org/std/photometadata/examples/IPTC-PhotometadataRef-Std2019.1.jpg

function main() {
    CHANGES=$1
    FOLDER=$2

    IMAGES=$(find ${FOLDER} -path ./blog/wp-content/plugins -prune -o -type f -iname "*.jpg" -print)

    for i in ${IMAGES}; do
        echo "Processing ${i}"

        exiv2 -T               ${i}
        exiv2 -k -m ${CHANGES} ${i}

        HASH=$(openssl rand -hex 32)
        exiv2 -k -M"set Exif.Image.ImageDescription Ascii ${HASH}" ${i}
    done
}

if [ "$#" -ne 2 ]; then
    echo "Apply <changes.txt> to all image files in <folder>."
    echo "Default: Recursively remove GPS tags, set Author info, fix file datetime."
    echo
    echo "Usage: $0 <changes.txt> <folder>"
else
    if [ ! -f "$1" ]; then
        echo
        echo "Error: Change file '$1' does not exist"
        echo
    elif [ ! -d "$2" ]; then
        echo
        echo "Error: Folder '$2' does not exist"
        echo
    else
        echo
        echo "Ok: Processing metadata."
        echo

        main $1 $2
    fi
fi

And a sample exiv2 command file:

# Command file format
# -------------------
# Empty lines and lines starting with # are ignored
# Each remaining line is a command. The format for command lines is
#   [[] ]
# cmd = set|add|del
#    set will set the value of an existing tag of the given key or add a tag
#    add will add a tag (unless the key is a non-repeatable IPTC key)
#    del will delete a tag
# key = Exiv2 Exif or IPTC key
# type =
#    Byte|Ascii|Short|Long|Rational|Undefined|SShort|SLong|SRational|Comment
#       for Exif keys, and
#    String|Date|Time|Short|Undefined  for IPTC keys
#    The format for IPTC Date values is YYYY-MM-DD (year, month, day) and
#    for IPTC Time values it is HH:MM:SS±HH:MM where HH:MM:SS refers to local
#    hour, minute and seconds and ±HH:MM refers to hours and minutes ahead or
#    behind Universal Coordinated Time.
#    A default type is used if none is explicitly given. The default type
#    is determined based on the key.
# value
#    The remaining text on the line is the value. It can optionally be enclosed in
#    double quotes ("value")
#

del  Exif.Image.GPSTag
del  Exif.GPSInfo.GPSVersionID
del  Exif.GPSInfo.GPSLatitudeRef
del  Exif.GPSInfo.GPSLatitude
del  Exif.GPSInfo.GPSLongitudeRef
del  Exif.GPSInfo.GPSLongitude
del  Exif.GPSInfo.GPSAltitudeRef
del  Exif.GPSInfo.GPSAltitude
del  Exif.GPSInfo.GPSDOP
del  Exif.GPSInfo.GPSImgDirectionRef
del  Exif.GPSInfo.GPSImgDirection
del  Exif.GPSInfo.GPSProcessingMethod

set  Exif.Image.Artist            Ascii    "Max Vilimpoc"
set  Exif.Image.Copyright         Ascii    "Copyright (c) 1999 - 2020 Max Vilimpoc, all rights reserved."

set  Iptc.Application2.Credit     String   "Max Vilimpoc"
set  Iptc.Application2.Copyright  String   "Copyright (c) 1999 - 2020 Max Vilimpoc, all rights reserved."

set  Xmp.dc.creator               XmpSeq   "Max Vilimpoc"
set  Xmp.dc.rights                LangAlt  "Copyright (c) 1999 - 2020 Max Vilimpoc, all rights reserved."
set  Xmp.iptc.CiUrlWork           XmpText  "https://vilimpoc.org"