IBM: improper authentication
Critical9.8CVE-2026-53709 · Published Jun 15, 2026
### Summary ContextForge ships a hardcoded HMAC-SHA256 signing key as the production default for `JWT_SECRET_KEY`, both in `mcpgateway/config.py` and in the project's own `.env.example`. The same default deployment ships `PLATFORM_ADMIN_EMAIL=admin@example.com` and `REQUIRE_USER_IN_DB=false`. Any party who can read the public repository can craft a JWT that the gateway accepts as an authenticated **platform administrator** without ever sending credentials, without an account existing in the database, and without any indicator distinguishing the forged token from a legitimate one. The attack is **unauthenticated**, **network-reachable**, **deterministic**, and **survives admin account deletion**, **password rotation**, and **session revocation** as long as the signing key is unchanged. This is the textbook profile of CWE-321 (Use of Hard-coded Cryptographic Key) combined with CWE-1188 (Insecure Default Initialization) and CWE-287 (Improper Authentication). The project's own `SECURITY.md` states that Snyk custom rules "enforce detection of hardcoded JWT secrets and basic auth credentials (CWE-798)" — i.e. the project explicitly classifies this exact pattern as a vulnerability in it...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| mcp-contextforge-gateway PyPI | < 1.0.2 | 1.0.2 |
Details and references
### Summary ContextForge ships a hardcoded HMAC-SHA256 signing key as the production default for `JWT_SECRET_KEY`, both in `mcpgateway/config.py` and in the project's own `.env.example`. The same default deployment ships `PLATFORM_ADMIN_EMAIL=admin@example.com` and `REQUIRE_USER_IN_DB=false`. Any party who can read the public repository can craft a JWT that the gateway accepts as an authenticated **platform administrator** without ever sending credentials, without an account existing in the database, and without any indicator distinguishing the forged token from a legitimate one. The attack is **unauthenticated**, **network-reachable**, **deterministic**, and **survives admin account deletion**, **password rotation**, and **session revocation** as long as the signing key is unchanged. This is the textbook profile of CWE-321 (Use of Hard-coded Cryptographic Key) combined with CWE-1188 (Insecure Default Initialization) and CWE-287 (Improper Authentication). The project's own `SECURITY.md` states that Snyk custom rules "enforce detection of hardcoded JWT secrets and basic auth credentials (CWE-798)" — i.e. the project explicitly classifies this exact pattern as a vulnerability in its supply chain policy, while simultaneously shipping it as the configured default for the production package (`version = "1.0.0"` per `pyproject.toml`). ### Affected source — exact references on `main` The complete vulnerable chain is contained in three files. All line references are against the current `main` branch tree. #### 1. Hardcoded signing key shipped in source `mcpgateway/config.py`: ```python jwt_secret_key: SecretStr = Field(default=SecretStr("my-test-key-but-now-longer-than-32-bytes")) ``` The same string is enumerated in the project's own weak-secret blocklist in the same file: ```python WEAK_VALUES: ClassVar[list[str]] = [ "my-test-key", "my-test-key-but-now-longer-than-32-bytes", # project self-identifies as weak "my-test-salt", "changeme", ... ] ``` The validator that consults `WEAK_VALUES` only emits a `logger.warning` and does not raise, abort startup, or refuse to sign tokens — even when `environment="production"` and `require_strong_secrets=True`: ```python @field_validator("jwt_secret_key", "auth_encryption_secret") @classmethod def validate_secrets(cls, v, info): ... if value.lower() in weak_secrets: logger.warning(f"SECURITY WARNING - {field_name}: Default/weak secret detected! ...") ... return v if isinstance(v, SecretStr) else SecretStr(value) ``` #### 2. The same weak value is shipped in `.env.example` The project's reference environment file at the repository root contains: ``` # JWT secret used to sign tokens # PRODUCTION: Use a strong, unique value JWT_SECRET_KEY=my-test-key-but-now-longer-than-32-bytes ``` and: ``` # Bootstrap admin credentials (email auth) # PRODUCTION: Change these values PLATFORM_ADMIN_EMAIL=admin@example.com PLATFORM_ADMIN_PASSWORD=changeme ``` `.env.example` is the file the documentation directs operators to copy as `.env` on first install. The same `.env.example` also sets the dev-permissive `HOST=0.0.0.0`, ensuring the gateway binds to all interfaces by default. A "PRODUCTION: change this" comment is not a control; it is a request that the operator perform a manual cryptographic rekeying step. #### 3. JWT verification does not consult the database `mcpgateway/utils/verify_credentials.py`, `verify_jwt_token()`: ```python payload = jwt.decode( token, key=get_jwt_public_key_or_secret(), # returns the SAME default secret algorithms=[settings.jwt_algorithm], # HS256 by default audience=settings.jwt_audience, # "mcpgateway-api" by default issuer=settings.jwt_issuer, # "mcpgateway" by default options={"verify_aud": True, "verify_iss": True, "require": ["exp"]}, ) ``` No database lookup, no certificate pinning,
More IBM advisories
All IBM| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Jul 17 | IBM Db2: remote code execution | High7.8 | No fix yet |
| Jul 8 | IBM API Connect: SQL injection | Critical9.1 | 10.0.8.9 |
| Jul 8 | IBM API Connect: attacker could gain unauthorized access to the application | High8.1 | 12.1.0.3 |
| Jun 15 | IBM: template injection | High | 1.0.0 |
| Jun 15 | Stored XSS Vulnerability Report – mcp-context-forge | Medium | 0.3.1 |
| Jun 15 | DNS TOCTOU race condition causes SSRF protection bypass (`/admin/gateways/test`) | Medium6.6 | 1.0.3 |