P1 privacy: EXIF and other metadata are not stripped from processed images #82

Open
opened 2026-08-09 03:49:19 +02:00 by clawbot · 0 comments
Collaborator

Verified against main at 61f42e6. This is the "strip EXIF and other metadata from processed images (privacy)" P1 item in TODO.md; confirmed genuinely missing — grep for StripMetadata across the repo returns nothing, and encode (internal/imageprocessor/imageprocessor.go:334-380) never sets a strip option.

libvips preserves metadata through a transform by default, so pixa currently re-publishes whatever the upstream image carried: GPS coordinates, camera serial numbers, capture timestamps, software fingerprints, and in some cases embedded thumbnails that can differ from the visible image.

This matters more for a proxy than for an ordinary encoder. An operator putting pixa in front of user-uploaded content reasonably assumes a resize strips incidental metadata, and nothing in the docs says otherwise. The embedded-thumbnail case is the sharp edge: a cropped image can leak the uncropped original.

Definition of done

  1. Metadata is stripped on every processed output path in encode.
  2. ICC colour profiles are handled deliberately, not dropped as collateral. Stripping the profile from a wide-gamut image without converting to sRGB first produces visibly wrong colour. Either convert to sRGB and strip, or retain the profile while stripping everything else. State the choice and reasoning in the PR.
  3. Orientation is applied before stripping, so removing the EXIF orientation tag does not leave the image rotated.
  4. format=orig passthrough (no transform) is decided explicitly: it is arguably a byte-for-byte proxy of the source, in which case it keeps metadata — but that must be a documented decision, not an accident. Document whichever way it goes.
  5. Whether stripping is configurable is a judgment call; default to always-strip and only add a key if there is a real reason.
  6. Failing tests first: a fixture with known EXIF (including GPS) produces output with no EXIF; an image with EXIF orientation renders in the correct orientation after stripping; a wide-gamut fixture does not shift colour.
  7. README documents the behavior. make check green.

Note

A test fixture with real EXIF is needed. Keep it small — repo policy caps total repository size, and test media is one of the few things allowed to be committed, so choose a minimal image rather than a camera original.

Verified against `main` at `61f42e6`. This is the "strip EXIF and other metadata from processed images (privacy)" P1 item in `TODO.md`; confirmed genuinely missing — `grep` for `StripMetadata` across the repo returns nothing, and `encode` (`internal/imageprocessor/imageprocessor.go:334-380`) never sets a strip option. libvips preserves metadata through a transform by default, so pixa currently re-publishes whatever the upstream image carried: GPS coordinates, camera serial numbers, capture timestamps, software fingerprints, and in some cases embedded thumbnails that can differ from the visible image. This matters more for a proxy than for an ordinary encoder. An operator putting pixa in front of user-uploaded content reasonably assumes a resize strips incidental metadata, and nothing in the docs says otherwise. The embedded-thumbnail case is the sharp edge: a cropped image can leak the uncropped original. ## Definition of done 1. Metadata is stripped on every processed output path in `encode`. 2. **ICC colour profiles are handled deliberately**, not dropped as collateral. Stripping the profile from a wide-gamut image without converting to sRGB first produces visibly wrong colour. Either convert to sRGB and strip, or retain the profile while stripping everything else. State the choice and reasoning in the PR. 3. Orientation is applied before stripping, so removing the EXIF orientation tag does not leave the image rotated. 4. `format=orig` passthrough (no transform) is decided explicitly: it is arguably a byte-for-byte proxy of the source, in which case it keeps metadata — but that must be a documented decision, not an accident. Document whichever way it goes. 5. Whether stripping is configurable is a judgment call; default to always-strip and only add a key if there is a real reason. 6. Failing tests first: a fixture with known EXIF (including GPS) produces output with no EXIF; an image with EXIF orientation renders in the correct orientation after stripping; a wide-gamut fixture does not shift colour. 7. README documents the behavior. `make check` green. ## Note A test fixture with real EXIF is needed. Keep it small — repo policy caps total repository size, and test media is one of the few things allowed to be committed, so choose a minimal image rather than a camera original.
clawbot added this to the 1.0.0 milestone 2026-08-09 03:49:19 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/pixa#82