Skip to content
The Digital Harm Project

For engineers building CSAM protection

Wire up the detection stack — without mishandling what you find.

The implementation companion to the technology chapter and the open-source toolkit: how the detection pipeline fits together, which hashing and matching infrastructure to use, and the one handling rule that turns good intentions into a criminal-exposure problem if you get it wrong.

01 · The pipeline

What a detection pipeline actually does.

Strip away the vendors and a CSAM detection system is four stages: ingest, hash, match, act. A file arrives (upload, message attachment, generated output); you compute one or more perceptual hashes of it; you compare those hashes against verified lists of known illegal material; and on a match you take a defined action — block, queue for human review, and, if you are a US provider, report. Everything else is detail layered on these four stages.

The two design decisions that matter early are where hashing runs and when matching happens. Hashing at the edge (client or upload handler) saves bandwidth but is easier to tamper with; hashing server-side on ingest is the common baseline. Matching can be synchronous (block the upload until it clears) or asynchronous (accept, then scan and retro-act); most teams run a fast known-hash check inline and push slower classifier work to a queue. Build the pipeline so a new hash source or classifier can be added as a stage without a rewrite — you will add several over time.

02 · Hashing

Perceptual hashing is the workhorse, not cryptographic.

A cryptographic hash (MD5, SHA-256) changes completely if a single pixel changes, so it only catches byte-identical files — useless once an image is resized, recompressed, or re-saved. Perceptual hashing produces a fingerprint that stays close for visually similar images, so a match survives the transformations offenders routinely apply. Matching is then a Hamming-distance threshold, not an equality check.

  • PhotoDNA (Microsoft) is the long-standing industry perceptual hash for images. Free for qualified organizations, but application-gated and slow to onboard — start the request before you need it (PhotoDNA).
  • PDQ and TMK+PDQF (Meta, open-source) are the unrestricted alternative: PDQ for images, TMK+PDQF for video. You can read the algorithm, run it without an application, and self-host the matching. This is usually where a small team starts (ThreatExchange / PDQ).
  • Cryptographic hashes still have a place — as a fast exact dedupe layer in front of perceptual matching, and for the file-identity records you keep for reporting. They are a complement, not the detection mechanism.

The open-source hashkit crate wraps perceptual hashing behind one Rust/WASM API so the same hashing runs server-side and at the edge without reimplementation.

03 · Matching the lists

Match against verified lists. Never build your own.

You do not assemble a corpus of known CSAM to match against — possessing one is both illegal and unnecessary. Instead you match against hash lists maintained by clearinghouses, which distribute only the fingerprints, never the images.

  • NCMEC Hash Sharing API — the verified industry list (millions of vetted hashes across PhotoDNA, PDQ, MD5 and more). Free for qualified US providers (NCMEC Hash Sharing).
  • IWF Hash List — the UK equivalent, used by 200+ platforms internationally, with category metadata (IWF Hash List).
  • Project Arachnid Shield API (Canadian Centre for Child Protection) — matching-as-a-service if you would rather not host the list and matcher yourself.

At small scale a linear Hamming-distance scan is fine. Past a few hundred thousand hashes, use multi-index hashing (MIH) so lookups stay sub-linear; hashkit-match implements MIH so you are not hand-rolling the index. Treat the hash list as sensitive infrastructure: the filenames and counts are restricted, and the safety guard CI in the toolkit blocks them from ever landing in a commit.

04 · Handling a match

The one rule you cannot break: do not mishandle the file.

Do not download, copy, move, screenshot, or assemble a store of suspected CSAM — not to “build a training set,” not to “preserve evidence,” not for QA. Doing so can itself be a criminal offense, even with good intent. Your system flags a location and a hash, not a saved copy.

When your pipeline matches apparent CSAM, the correct sequence is: remove or block public access, restrict the original in place (do not exfiltrate it), and, if you are a US-based provider, report to the NCMEC CyberTipline. Under 18 U.S.C. § 2258A that report is a legal duty once you have actual knowledge, with civil and criminal penalties for failure; NCMEC exposes an API so reporting is part of the pipeline, not a manual afterthought. Preservation happens through the legal-process channel and your normal retention of the account record, not by your team making copies of the material.

Two engineering implications follow. First, design the match handler so the file itself is never written to a new location, a log, an error report, or a screenshot — pass references (storage key, hash, account ID), never bytes. Second, put a named human and a legal-escalation path behind the queue; an automated match is a report trigger and a human-review trigger, and the most serious categories should reach counsel quickly. See For Compliance Teams for the reporting-evidence and retention records an auditor will later expect.

05 · If you build generation

Generative pipelines need prompt-side and output-side defense.

If you run image or video generation, hash-matching known material is not enough — the risk is novel synthetic CSAM, which by definition is not on any list. Defense is layered, and the cheapest layer is the earliest:

  • Prompt-side filtering blocks known abuse-seeking prompts and combinations before any compute is spent. It is imperfect against obfuscation but removes the casual majority and creates a logged signal.
  • Output classifiers (Thorn Safer, Hive AI, and similar) score generated frames for apparent CSAM before delivery. This is where novel material is caught; budget for it as a real inference cost.
  • Training-data hygiene — scan and document that training sets were checked against known-CSAM hashes, after the LAION findings made this a baseline expectation rather than a nicety.
  • Provenance — sign outputs with C2PA / Content Credentials so downstream systems can distinguish your generations and so abuse is traceable.

The legal frame matters for prioritization: the ENFORCE Act and TAKE IT DOWN Act extend criminal-equivalent treatment to AI-generated CSAM, so “it was synthetic” is not a defense. The background is in Chapter 04: AI-Generated Content.

06 · Testing safely

Validate the pipeline without ever touching real material.

You cannot use real CSAM to test — ever, for any reason. The pipeline is still fully testable, because hashing and matching are content-agnostic: a matcher that correctly flags a benign image whose hash you planted in a test list is exercising the exact same code path it would on real input.

  • Synthetic hash vectors — generate perceptual hashes of ordinary, licensed test images, load them into a fixture “known” list, and assert the pipeline matches, near-matches (post-resize), and correctly ignores unrelated images. This covers ingest, hashing, threshold tuning, and the match handler.
  • detectkit-test in the toolkit ships exactly these benign-by-construction conformance vectors, so your matcher's Hamming-distance behavior is verified against a shared baseline rather than ad-hoc fixtures.
  • Handler tests — assert the negative behaviors explicitly: that a match writes no copy of the file, emits no bytes to logs, and produces a correctly-shaped report payload from references only.

Treat “a match never causes the file to be copied anywhere” as a first-class test, not a code-review hope.

07 · The toolkit

What the open-source portfolio gives you.

The FightCSAM portfolio is the buildable layer beneath the detection landscape — designed so any platform can wire up the same protection as a much larger one, without weeks of per-provider integration. The pieces a developer reaches for first:

  • hashkit — one Rust/WASM perceptual-hashing API that runs identically server-side and at the edge.
  • hashkit-match — multi-index Hamming-distance matching that stays sub-linear across millions of hashes.
  • detectkit-test — benign conformance vectors for validating a matcher without real material.
  • The integration and list-infrastructure tools — drop-in middleware that compresses PhotoDNA-style onboarding and standardizes CyberTipline reporting payloads.

Every package ships under a safety policy enforced in CI: no hash-list filenames, no image binaries outside a tight allowlist, no credential patterns. The repository and per-tool status live on the tools page.

08 · Where to start

A first-week sequence for a small team.

If you host user images or run generation and have nothing in place, this order gets you from zero to a defensible baseline without waiting on any single gated dependency:

  • Day 1 — start the gated requests. File for PhotoDNA and NCMEC Hash Sharing access now; they take time. In parallel, stand up open PDQ hashing so you are not blocked waiting.
  • Day 2–3 — build ingest and hashing. Hash every uploaded or generated image on ingest with hashkit; store references, never the material itself.
  • Day 3–4 — wire matching and the handler. Match against your available list with hashkit-match; implement the match handler with the no-copy guarantee and a human-review queue. Test it end-to-end with detectkit-test vectors.
  • Day 5 — reporting and escalation. Integrate the CyberTipline report path, designate a primary and backup reporter, and write down the legal-escalation contact. Document the whole flow for the audit you will face later.

That is the minimum viable stack. The strategic version — what to add as you scale, and where executives face personal exposure — is in For Tech CEOs; the audit and documentation companion is For Compliance Teams.

Where this material lives

Reference into the research and the repo.

The pages worth bookmarking for the deeper picture:

Notes on this page

  • Implementation guidance, not legal advice. The § 2258A reporting duty and the handling rules carry criminal exposure; counsel experienced in child-safety law is the right escalation for entity-specific questions.
  • Tool and vendor naming is descriptive of the working ecosystem, not an endorsement. We are not affiliated with the named providers.
  • The single most important line on this page: a match flags a location and a hash, never a saved copy. If your design ever needs the bytes somewhere new, stop and re-read Handling a match.
  • If your team is exposed to this material operationally, the mental-health load is real. See For Survivors for the trauma-informed resources we'd point a reviewer toward.