Apr 8, 2026·6 min read·2 visits
An adversary-in-the-middle can spoof TimeStamping Authority identities in rfc3161-client < 1.0.6 by injecting crafted certificates into the PKCS#7 bag, bypassing Common Name validation.
The rfc3161-client Python library prior to version 1.0.6 contains a trust boundary confusion vulnerability in its Time-Stamp Protocol (TSP) implementation. A flawed topological heuristic used for identifying the signer's leaf certificate allows an attacker to inject spoofed certificates and bypass authorization checks.
The rfc3161-client Python library provides implementation support for the Time-Stamp Protocol (TSP) defined in RFC 3161. The software processes TimeStampResponse (TSR) payloads, which encapsulate a PKCS#7 structured message containing cryptographically signed timestamp data. These structures rely on a combination of cryptographic signatures and parsed certificate fields to assert the identity of a TimeStamping Authority (TSA).
Versions of the library prior to 1.0.6 suffer from an improper certificate validation flaw tracked as CWE-295. The vulnerability manifests as a trust boundary confusion between the underlying cryptographic validation backend and the Python-based authorization logic. The library incorrectly parses the unstructured certificate bag within the PKCS#7 data to identify the primary signing certificate.
A structural flaw in the leaf certificate selection routine permits an adversary to inject extraneous certificates into the response bag. The library subsequently validates the expected Common Name and Extended Key Usage against the injected certificate. Simultaneously, the cryptographic backend verifies the digital signature using the genuine certificate hidden within the same bag.
This decoupling allows an adversary-in-the-middle to spoof a trusted TSA identity. The resulting system processes maliciously modified or intercepted timestamps as fully authorized and legitimate, undermining the non-repudiation guarantees of the protocol.
The vulnerability originates in the rfc3161_client.verify.Verifier._verify_leaf_certs() method. The PKCS#7 standard defines the certificates field within SignedData as an unordered set of certificates, providing no structural guarantee of the trust chain's hierarchy. Software parsing this structure must accurately identify the specific certificate corresponding to the signature.
To identify the signer's certificate, the library applied a naive topological heuristic. The routine iterated through all certificates in the SignedData bag and selected the first certificate that did not function as an issuer for any other certificate in that same bag. This assumes the PKCS#7 bag exclusively contains a linear chain of trust terminating at the true leaf.
This heuristic fails when processing adversarial input. An attacker modifying the unauthenticated structure of the certificate bag invalidates the linearity assumption completely. By appending arbitrary certificates, the attacker dictates the output of the topological search.
The cryptographic backend processes the signature using the mathematically valid leaf, ignoring the extraneous certificates. The Python logic performs authorization against the heuristically selected certificate. This creates a fatal divergence where identity verification and cryptographic integrity apply to two separate entities within the same payload.
The vulnerable implementation relied on list comprehensions to map issuer-subject relationships. The logic disqualified any certificate that appeared as an issuer for another certificate present in the bag.
# Vulnerable heuristic in pre-1.0.6 implementations
for cert in certs:
if not [c for c in certs if c.issuer == cert.subject]:
leaf_certificate_found = cert
breakThe patch in commit 4f7d372297b4fba7b0119e9f954e4495ec0592c0 removes this heuristic entirely. The revised implementation extracts the issuer and serial_number directly from the SignerInfo structure. The SignerInfo structure explicitly binds the cryptographically validated signature to a specific certificate identifier.
# Annotated conceptual fix
# The library now enforces strict mapping via issuerAndSerialNumber
for cert in certs:
if cert.issuer == signer_info.issuer and cert.serial_number == signer_info.serial_number:
leaf_certificate_found = cert
breakAdditionally, the patch introduces a structural constraint check. The library now enforces len(signer_infos) == 1 during verification. This prevents ambiguity attacks where multiple valid signers might confuse the authorization mapping logic.
Exploitation requires an adversary to establish a network position capable of intercepting and modifying communication between the client and a genuine TSA. This technique aligns with MITRE ATT&CK T1557 (Adversary-in-the-Middle). The attacker passively allows the client's request to reach the genuine TSA and captures the legitimate TimeStampResponse.
The attacker modifies the unordered PKCS#7 SignedData.certificates bag within the captured response. They append a dummy certificate constructed to list the genuine TSA's leaf certificate as its issuer. This injection forces the vulnerable topological heuristic to disqualify the genuine leaf, as it now appears to function as an intermediate issuer.
The attacker then appends a second, spoofed certificate. This certificate contains the common_name pinned by the target client and the required id-kp-timeStamping Extended Key Usage attribute. Since this spoofed certificate issues no other certificate in the bag, the heuristic designates it as the leaf.
The regression test included in the fix repository demonstrates this exact payload structure. The test confirms that providing a spoofed common name inside an injected certificate bypasses the logic in vulnerable versions.
def test_verify_rejects_injected_cert_bag_spoofing_common_name() -> None:
cert_path = _FIXTURE / "test_tsa" / "ts_chain.pem"
tsr_path = _FIXTURE / "test_tsa" / "response-injected-certs.tsr"
# ... initialization ...
# Attempt to verify with the spoofed common_name
verifier = VerifierBuilder(
common_name="CN=Spoofed TSA",
roots=[root_cert],
intermediates=[intermediate_cert],
).build()
# In patched versions, this correctly raises a VerificationError
with pytest.raises(VerificationError, match="name provided in the opts does not match"):
verifier.verify(ts_response, message)The direct consequence of this vulnerability is a complete authorization bypass for timestamp verification. Applications relying on rfc3161-client to guarantee the origin of a timestamp will accept intercepted or replayed timestamps from an adversary. The application registers the timestamp as originating from its strictly pinned, trusted authority.
The CVSS v3.1 base score of 6.2 reflects a Medium severity flaw. The vector evaluates to Local (AV:L), reflecting the library's role in parsing locally received files, though the practical execution involves network interception. The attack requires low complexity, no special privileges, and zero user interaction.
The integrity of the timestamp validation process sustains high impact. An attacker effectively dictates the trusted identity associated with cryptographic operations. Confidentiality and availability remain unaffected, as the attack strictly concerns authorization mapping and does not expose underlying plaintext or crash the service.
The primary remediation requires upgrading rfc3161-client to version 1.0.6. This release contains the deterministic SignerIdentifier lookup routine and eliminates the vulnerable topological heuristic. The command pip install -U rfc3161-client applies the necessary dependency update.
In environments where immediate patching is impossible, network-level controls offer partial mitigation. Enforcing strict Transport Layer Security (TLS) certificate pinning on the network channel communicating with the TSA prevents the adversary-in-the-middle interception required to manipulate the TSR payload.
Developers must audit downstream applications processing PKCS#7 or CMS structures. Codebases must never rely on unstructured bag ordering or topological inferences to determine cryptographic relationships. Cryptographic standards provide explicit bindings, such as issuerAndSerialNumber or SubjectKeyIdentifier, which applications must strictly honor.
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
rfc3161-client Trail of Bits | < 1.0.6 | 1.0.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-295 |
| Attack Vector | Local / Adversary-in-the-Middle |
| CVSS Score | 6.2 |
| Impact | Authorization Bypass |
| Exploit Status | Proof of Concept |
| CISA KEV | Not Listed |
The software does not validate, or incorrectly validates, a certificate.