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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions