Fake-redaction forensics Recoverable
v0.1.1MITNode.js / Lambda4 checks + 2 tiers
SHA-256 · input a4f2‥e19 → output a4f2‥e19 · identical — the bar changed nothing underneath
Your PDF is processed in memory on our server, never written to disk or logged, and discarded the moment the response is sent. No third parties, no AI, no tracking of file contents.

Is it actually
redacted?

Most redactions are just a black box drawn over live text that anyone can copy straight out. Check finds text hidden under filled boxes, recoverable prior revisions, metadata leaks, and unapplied annotations — and can lift the fake bars to reveal exactly what they failed to hide. Powered by the unseal package, for Node.js and Lambda.

npmGitHub
01Live audit

Upload any PDF. No data is stored. No AI is used for Tier 1.

Analysis depth

02Four checks
01Text under boxCRITICAL

The most common mistake: a black rectangle drawn on top of text, but the text operators remain in the content stream. Check scans every filled rectangle against underlying text items and surfaces the hidden content verbatim.

02Incremental saveHIGH

When a PDF is saved incrementally, prior content is appended rather than replaced. Earlier versions of the document sit in the same byte stream. Check detects the %%EOF signature pattern and flags the recoverable revision.

03Metadata leakMEDIUM

Title, Author, Subject, Keywords, and XMP streams survive many redaction workflows. Redacted names or document titles often remain in DocInfo or embedded XMP even after the visible content is blacked out.

04Pending annotationsCRITICAL

PDF/A and most redaction tools create Redact-subtype annotations to mark regions for removal. They are only effective after the tool applies them. Many workflows skip that step — the annotations are present, the text beneath is untouched.

03Usage

Basic audit

import { audit } from '@liiift-studio/unseal'
import { readFile } from 'node:fs/promises'

const pdf = await readFile('document.pdf')
const report = await audit(pdf.buffer)

if (!report.clean) {
  for (const finding of report.findings) {
    console.log(finding.severity, finding.check, finding.recoveredText)
  }
}

Reveal — lift the fake bars so the hidden text is readable

import { unseal } from '@liiift-studio/unseal'

const result = await unseal(pdf.buffer)
// result.pdf         — the document with the fake redaction stripped,
//                      so the text it was hiding is now readable
// result.findings    — what was recovered, and how it was hidden
// result.auditReport — full audit of the original

CLI

npx @liiift-studio/unseal audit document.pdf
npx @liiift-studio/unseal audit document.pdf --preset forensic --json
npx @liiift-studio/unseal strip document.pdf --output unsealed.pdf --report findings.json