MarkMyAss

Lab: PDF Metadata#

Current status: Verified · Detect: Yes · Remove: Yes · Last tested: 2026-08-13

← Back to the Lab · ← Back to the MarkMyAss cleaner


What this signal is#

PDF files carry two independent metadata containers:

Either can carry provenance information -- the tool that generated the PDF, an author name, timestamps -- independent of anything about the PDF's visible content.

What MarkMyAss can test#

Detection reads both containers directly from the PDF object graph via pikepdf (a Python binding to qpdf). Implementation: src/ghostmark/detectors/metadata.py.

What MarkMyAss can remove#

Both the /Info dictionary and the /Metadata (XMP) stream are deleted entirely from the PDF's object graph -- not blanked, removed. Pages, fonts, images, text, links, and page order are untouched; MarkMyAss edits the PDF's object graph directly rather than rasterizing or re-rendering it. Implementation: src/ghostmark/cleaners/pdf.py.

After cleaning, MarkMyAss reopens the produced PDF and confirms it's still structurally valid (parses, page count matches) before handing it back -- a metadata-removal bug that corrupts the file is treated as a cleaning failure, not a success.

What MarkMyAss cannot test#

Verification methodology#

Independent verification uses ExifTool (exiftool -j -G1 -a -s FILE), a long-established, widely trusted third-party tool MarkMyAss does not control. Every property ExifTool reports is categorized into embedded_metadata / structural / filesystem / computed so that, for example, PDF:PageCount (a structural fact needed for the file to make sense) is never confused with PDF:Author (metadata MarkMyAss actually targets). See src/ghostmark/independent_verify.py for the exact categorization rules.

A result only counts as independently verified clean when ExifTool finds zero embedded_metadata-category tags in the cleaned output.

Reproducible test commands#

ghostmark inspect src/ghostmark/corpus/pdf/docinfo-xmp.pdf --json
ghostmark clean src/ghostmark/corpus/pdf/docinfo-xmp.pdf
ghostmark verify src/ghostmark/corpus/pdf/docinfo-xmp.ghostmark.pdf --receipt receipt.json

# Independently, with ExifTool directly:
exiftool -j -G1 -a -s src/ghostmark/corpus/pdf/docinfo-xmp.pdf
exiftool -j -G1 -a -s src/ghostmark/corpus/pdf/docinfo-xmp.ghostmark.pdf

Covered by the automated regression suite: tests/test_pdf.py, tests/test_corpus.py, and the real-ExifTool integration suite tests/integration/test_exiftool_real.py.

Sources#

Something outdated or inaccurate?#

Open an issue or submit a pull request against src/ghostmark/web/content/lab/pdf-metadata.md.

Last reviewed: 2026-08-13