id: PYSEC-2026-2548 published: "2026-07-13T15:15:44.116389Z" modified: "2026-07-13T16:04:25.541100Z" aliases: - CVE-2026-6420 - GHSA-q8w6-w55c-ccv5 summary: Keylime has a hardcoded attestation challenge nonce that allows replay attacks details: "## CVE-2026-6420: Hardcoded attestation challenge nonce allows replay attacks\n\n### Impact\n\nThe `CertificationParameters.generate_challenge()` method in the push attestation protocol uses a hardcoded challenge nonce instead of generating a cryptographically random value. This removes the nonce-based replay protection from TPM quote attestation.\n\nAn attacker with root access on a monitored agent node can exploit this by stockpiling valid TPM quotes (using `tpm2_quote` with the known nonce) before compromising the system, then replaying them to evade detection by the verifier. The push attestation timeout (~10s) constrains the generation window, but TPM throughput allows stockpiling ~50-200 quotes, enabling approximately 8-33 minutes of undetected compromise with default settings.\n\nThe attack is limited to a single agent node (AK signature binding prevents cross-agent replay). The pull-mode (legacy) attestation path is not affected.\n\n**Affected versions:** >= 7.14.0, <= 7.14.1\n\n**CVSS:** 6.3 Medium (`CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:L`)\n\n| Metric | Value | Rationale |\n|---|---|---|\n| AV | Local | Exploitation requires local access to the agent machine (stop agent, access TPM, run replacement). The network transmission of quotes to the verifier is normal protocol operation. |\n| AC | Low | Deterministic attack: publicly visible nonce, standard `tpm2-tools`, no race conditions. |\n| PR | High | Root on a legitimate enrolled node is required. The vulnerability does not help gain access -- it only helps evade detection after root is obtained. No value against a machine the attacker already controls. |\n| UI | None | Fully automated after initial setup. |\n| S | Unchanged | AK signature binding confines impact to the single compromised agent. |\n| C | High | Compromised node continues receiving bootstrap keys, payloads, and secrets intended for trusted nodes. |\n| I | High | Verifier cannot distinguish a healthy system from a fully compromised one during the evasion window. |\n| A | Low | Only the compromised agent's revocation and incident response are suppressed; the system as a whole remains operational. |\n\nThe base score does not fully capture the operational severity: Keylime exists to detect machine compromise, so 8-33 minutes of undetected compromise is operationally critical. The fix is a one-line change and should be applied immediately regardless of the base score.\n\n### Patches\n\nThe fix restores the original random nonce generation (one-line change in `keylime/models/verifier/evidence.py`):\n\n```python\n# Before (vulnerable):\ndef generate_challenge(self, bit_length):\n # self.challenge = Nonce.generate(bit_length)\n self.challenge = bytes.fromhex(\"49beed365aac777dae23564f5ad0ec\")\n\n# After (fixed):\ndef generate_challenge(self, bit_length):\n self.challenge = Nonce.generate(bit_length)\n```\n\nUsers should upgrade to the version containing this fix (7.14.2).\n\n### Workarounds\n\nThere is no complete workaround. The following existing mechanisms provide partial mitigation and are already active by default (no configuration needed):\n\n1. **TPM clock monotonicity check** limits each distinct stockpiled quote to a single use, bounding the total evasion time.\n2. **Push attestation timeout** (default 10s) prevents the attacker from going silent and constrains the quote generation window.\n\nReducing `quote_interval` increases the attestation frequency but does not prevent the stockpiling attack.\n\n### References\n\n- CWE-329: Generation of Predictable IV/Nonce (primary -- hardcoded nonce in cryptographic attestation protocol)\n- CWE-547: Use of Hard-Coded, Security-relevant Constants (hardcoded constant left in production code)\n- CWE-294: Authentication Bypass by Capture-replay (consequence -- enables replay attacks)\n- CWE-1241: Use of Predictable Algorithm in Random Number Generator\n- Introducing commit: [`2bf91197`](https://github.com/keylime/keylime/commit/2bf91197) via [PR #1814](https://github.com/keylime/keylime/pull/1814)\n- TCG TPM 2.0 Library Specification, Part 1, Section 18.4 (TPM2_Quote)\n- IETF RATS Architecture (RFC 9334), Section 8 (Freshness)" affected: - package: name: keylime ecosystem: PyPI purl: pkg:pypi/keylime ranges: - type: ECOSYSTEM events: - introduced: 7.14.0 - fixed: 7.14.2 versions: - 7.14.0 - 7.14.1 references: - type: WEB url: https://github.com/keylime/keylime/security/advisories/GHSA-q8w6-w55c-ccv5 - type: ADVISORY url: https://nvd.nist.gov/vuln/detail/CVE-2026-6420 - type: WEB url: https://access.redhat.com/security/cve/CVE-2026-6420 - type: WEB url: https://bugzilla.redhat.com/show_bug.cgi?id=2458889 - type: PACKAGE url: https://github.com/keylime/keylime - type: PACKAGE url: https://pypi.org/project/keylime - type: ADVISORY url: https://github.com/advisories/GHSA-q8w6-w55c-ccv5 severity: - type: CVSS_V3 score: CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:L