Skip to content

Security: Hardcoded default JWT secret and encryption key in MCP server #50

@CrepuscularIRIS

Description

@CrepuscularIRIS

Bug Description

The MCP server ships with hardcoded default values for the JWT secret key and API key encryption key in MCP/config/settings.py. If operators deploy without setting JWT_SECRET_KEY and ENCRYPTION_KEY environment variables, any attacker who reads the source code can forge authentication tokens and decrypt stored API keys.

Location

MCP/config/settings.py:37-48

Reproduction

# Using the default secrets from source code:
import jwt
from datetime import datetime, timedelta

# Default from settings.py line 39
secret = "simplemem-secret-key-change-in-production"

# Forge a token for any user_id
forged = jwt.encode(
    {"user_id": "target-user", "table_name": "simplemem_target-user",
     "created_at": "2025-01-01T00:00:00", "exp": int((datetime.utcnow() + timedelta(days=30)).timestamp())},
    secret, algorithm="HS256"
)
# This token will pass verify_token() on any default deployment

Stack Trace

N/A — this is a configuration vulnerability, not a crash.

Impact

  • Token forgery: Any attacker can create valid JWT tokens for arbitrary user IDs
  • API key theft: The default encryption key (simplemem-encryption-key-32bytes! on line 47) allows decrypting all stored API keys
  • Full account takeover: Combined with the forged token, an attacker can access any user's memories and API keys

Suggested Fix

# Option 1: Fail-fast if secrets are not configured
jwt_secret_key: str = field(default_factory=lambda: os.environ["JWT_SECRET_KEY"])
# This will raise KeyError at startup if not set

# Option 2: Generate random secrets at first run and persist them
import secrets
jwt_secret_key: str = field(default_factory=lambda: os.getenv(
    "JWT_SECRET_KEY",
    secrets.token_urlsafe(32)  # At minimum, generate a random default
))

Additionally, add a startup warning or hard failure when default secrets are detected.


Found via automated codebase analysis. Happy to submit a PR if confirmed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions