T09 · Insecure Skill Coding Practices
- Location
scripts/babylon-client.ts:20- Finding
API Key Disclosure Through an Unrestricted Custom Endpoint
- Content
View full analysis
Vulnerability Details
File Location:
scripts/babylon-client.ts, lines 20–48; related configuration documentation inSKILL.md, line 77
Vulnerability Type: Credential disclosure through insufficient endpoint validation
Risk Level: HighVulnerable Code
ts const API_KEY = loadApiKey(); const BASE_URL = process.env.BABYLON_URL || 'https://play.babylon.market'; const MCP_ENDPOINT = `${BASE_URL}/mcp`; interface MCPResponse<T = unknown> { jsonrpc: '2.0'; id: number; result?: { content: Array<{ type: 'text'; text: string }>; isError: boolean; }; error?: { code: number; message: string; data?: unknown; }; } /** * Call an MCP tool via JSON-RPC 2.0 */ async function callTool<T>(toolName: string, args: Record<string, unknown> = {}): Promise<T> { const response = await fetch(MCP_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Babylon-Api-Key': API_KEY, },The same behavior also occurs in the account identity request at lines 86–90:
ts const response = await fetch(`${BASE_URL}/api/auth/whoami`, { headers: { 'X-Babylon-Api-Key': API_KEY, 'Accept': 'application/json', }, });Technical Analysis
The client reads the destination directly from the
BABYLON_URLenvironment variable without validating its scheme, hostname, port, or trust relationship. It then sends the value ofBABYLON_API_KEYin theX-Babylon-Api-Keyheader to that destination.Network authentication is necessary for the Skill's declared Babylon functionality when requests are sent to the documented production service. However, forwarding the production credential to any environment-selected origin does not enforce the credential's intended trust boundary. The code permits both attacker-controlled HTTPS origins and plaintext HTTP destinations.
...[truncated 2000 chars]
- Remediation
View remediation
Remediation Suggestions
-
Make the production endpoint immutable unless custom-instance support is explicitly required:
ts const BASE_URL = 'https://play.babylon.market'; -
If custom endpoints are required, parse and validate them with the
URLclass:- Require
https:. - Reject embedded usernames and passwords.
- Reject fragments and unexpected paths.
- Restrict ports where practical.
- Normalize and compare the origin against an explicit allowlist.
- Require
-
Permit plaintext HTTP only for explicit loopback development addresses such as
127.0.0.1orlocalhost, never for remote hosts. -
Use separate, origin-scoped credentials for custom Babylon instances. Do not send a production Babylon key to a custom origin.
-
Require an explicit opt-in or confirmation before sending credentials to a non-production endpoint, and display the normalized destination origin.
-
Document the credential-disclosure implications of
BABYLON_URL. -
Apply least-privilege scopes and expiration to API keys where supported, and provide a straightforward revocation and rotation process.
-
