Detecting Signature Compromise
Detecting Signature Compromise
SignaturesCompromiseDetector is the entry point for this guide: it inspects
a signed document’s revision history for indicators that content was added
after the last signature was applied, and reports what it finds as a
CompromiseCheckResult. This is the security surface covered by this cluster
of the knowledge base — it does not cover creating or applying signatures,
or document encryption; it only examines signatures that already exist on a
document.
Running a Compromise Check
Construct SignaturesCompromiseDetector with the document you want to
inspect, then call SignaturesCompromiseDetector.check(). The check walks
every signature already present on the document and looks for unsigned bytes
appended after the last signed revision — a sign that content may have been
layered on afterward — while tolerating legitimate long-term-validation
material (such as a document security store or archive timestamp) added by a
later, covering signature.
Interpreting the Result
SignaturesCompromiseDetector.check() returns a CompromiseCheckResult with
four properties:
CompromiseCheckResult.has_compromised_signatures—Trueif any signature showed a tamper indicator.CompromiseCheckResult.compromised— mirrorsCompromiseCheckResult.has_compromised_signatures, provided as a read-only convenience alias.CompromiseCheckResult.signatures_coverage— the number of signatures the detector examined on the document.CompromiseCheckResult.reasons— a list of short strings describing why the document was flagged, when it was.
A document with no signatures, or no document at all, is reported as not
compromised, with CompromiseCheckResult.signatures_coverage equal to 0.
Tips and Best Practices
- Treat
CompromiseCheckResult.compromisedandCompromiseCheckResult.has_compromised_signaturesas interchangeable — they always report the same value. - Check
CompromiseCheckResult.signatures_coveragebefore trusting aFalseresult: a coverage of0means the detector found no signatures to examine, not that existing signatures were verified as intact. - Read
CompromiseCheckResult.reasonswhenCompromiseCheckResult.has_compromised_signaturesisTrue— the list explains which heuristic triggered, which is useful when logging or surfacing the result to a reviewer. SignaturesCompromiseDetectorinspects revision history for tamper indicators; it does not validate cryptographic signature integrity itself, so pair it with the document’s own signature-validation results where that matters to your workflow.
Common Issues
| Issue | Cause | Fix |
|---|---|---|
CompromiseCheckResult.signatures_coverage is 0 for a document you know is signed | SignaturesCompromiseDetector was constructed without a document, or the document object has no accessible signatures | Confirm the document passed to SignaturesCompromiseDetector exposes its signatures before calling SignaturesCompromiseDetector.check() |
CompromiseCheckResult.reasons is empty even though you expected an explanation | CompromiseCheckResult.has_compromised_signatures is False for this document | Reasons are only populated when a compromise indicator was actually found; an empty list on a clean result is expected |
| A legitimately updated PDF (e.g. one with an added long-term-validation timestamp) is flagged as compromised | The later addition is not fully covered by a subsequent signature or is not recognized as validation-only material | Re-run the check after confirming the update was made by a proper covering signature or timestamp, and inspect CompromiseCheckResult.reasons for the specific trigger |
FAQ
What does CompromiseCheckResult.compromised actually check?
It reports the same value as
CompromiseCheckResult.has_compromised_signatures: whether
SignaturesCompromiseDetector.check() found any tamper indicator across the
document’s signatures.
Does a signatures_coverage of 0 mean the document is safe?
No — it means no signatures were found to examine. SignaturesCompromiseDetector
cannot report on signatures it cannot see, so a 0 coverage is a “nothing to
check” result, not a confirmation of integrity.
Can SignaturesCompromiseDetector create or verify a cryptographic signature?
No. It only inspects a document’s existing revision history for indicators that content was added after the last signature. Creating, applying, or cryptographically validating signatures is outside what this class does.
Will adding a legitimate timestamp after signing always trigger a compromise finding?
Not necessarily. The detector is designed to tolerate a later addition that is
itself covered by a subsequent signature, or that only adds validation
material rather than new content. Check CompromiseCheckResult.reasons if you
see an unexpected finding.
API Reference Summary
| Class/Method | Description |
|---|---|
SignaturesCompromiseDetector | Inspects a signed document for tamper indicators after the last signature |
SignaturesCompromiseDetector.check() | Runs the check and returns a CompromiseCheckResult |
CompromiseCheckResult | The outcome of a compromise check |
CompromiseCheckResult.compromised | Read-only alias for CompromiseCheckResult.has_compromised_signatures |
CompromiseCheckResult.has_compromised_signatures | Whether a tamper indicator was found |
CompromiseCheckResult.signatures_coverage | The number of signatures examined |
CompromiseCheckResult.reasons | Short strings explaining any finding |