Detecting Signature Compromise

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_signaturesTrue if any signature showed a tamper indicator.
  • CompromiseCheckResult.compromised — mirrors CompromiseCheckResult.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.compromised and CompromiseCheckResult.has_compromised_signatures as interchangeable — they always report the same value.
  • Check CompromiseCheckResult.signatures_coverage before trusting a False result: a coverage of 0 means the detector found no signatures to examine, not that existing signatures were verified as intact.
  • Read CompromiseCheckResult.reasons when CompromiseCheckResult.has_compromised_signatures is True — the list explains which heuristic triggered, which is useful when logging or surfacing the result to a reviewer.
  • SignaturesCompromiseDetector inspects 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

IssueCauseFix
CompromiseCheckResult.signatures_coverage is 0 for a document you know is signedSignaturesCompromiseDetector was constructed without a document, or the document object has no accessible signaturesConfirm the document passed to SignaturesCompromiseDetector exposes its signatures before calling SignaturesCompromiseDetector.check()
CompromiseCheckResult.reasons is empty even though you expected an explanationCompromiseCheckResult.has_compromised_signatures is False for this documentReasons 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 compromisedThe later addition is not fully covered by a subsequent signature or is not recognized as validation-only materialRe-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/MethodDescription
SignaturesCompromiseDetectorInspects a signed document for tamper indicators after the last signature
SignaturesCompromiseDetector.check()Runs the check and returns a CompromiseCheckResult
CompromiseCheckResultThe outcome of a compromise check
CompromiseCheckResult.compromisedRead-only alias for CompromiseCheckResult.has_compromised_signatures
CompromiseCheckResult.has_compromised_signaturesWhether a tamper indicator was found
CompromiseCheckResult.signatures_coverageThe number of signatures examined
CompromiseCheckResult.reasonsShort strings explaining any finding

See Also