T09 · Insecure Skill Coding Practices
- Location
scripts/kalshi_paper.ts:217- Finding
Unrestricted Market API Base URL Enables Blind Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/kalshi_paper.ts, lines 217-245
Vulnerability Type: Blind Server-Side Request Forgery (SSRF)
Risk Level: MediumVulnerable Code
ts function getKalshiBaseUrl(args: CliMap): string { const raw = (args["kalshi-base-url"] as string | undefined) ?? process.env.KALSHI_BASE_URL ?? "https://api.elections.kalshi.com/trade-api/v2"; return raw.replace(/\/+$/, ""); } async function fetchJson(url: string): Promise<unknown> { const res = await fetch(url, { method: "GET", headers: { accept: "application/json", "user-agent": "openclaw-skills-kalshi-paper-trading/1.0", }, }); const text = await res.text(); let json: unknown; try { json = JSON.parse(text); } catch { json = { raw: text }; } if (!res.ok) { throw new Error(`HTTP ${res.status} for ${url}: ${typeof json === "object" ? JSON.stringify(json) : String(json)}`); } return json; }The resulting URL is used by
fetchKalshiMarket:ts const baseUrl = getKalshiBaseUrl(args); const url = `${baseUrl}/markets/${encodeURIComponent(marketTicker)}`; const response = await fetchJson(url) as { market?: KalshiMarketPayload };Technical Analysis
The
sync-marketandbuy-from-marketcommands accept a network destination from either the--kalshi-base-urlcommand-line option or theKALSHI_BASE_URLenvironment variable. The value is used without validating its scheme, hostname, port, resolved IP address, or redirect destination.Node.js
fetchfollows HTTP redirects by default. Therefore, restricting the final path to/markets/<ticker>does not prevent exploitation: an attacker-controlled initial server can redirect the request to a loopback, private-network, link-local, or cloud metadata address.Response-shape validation occurs only after the request and any redirects have completed. An invalid market response may stop database processing, but it does not pre ...[truncated 2071 chars]
- Remediation
View remediation
Remediation Suggestions
-
Allowlist the production endpoint
- Permit only the official Kalshi HTTPS hostname during normal operation.
- Compare parsed hostnames exactly rather than using suffix or substring checks.
-
Validate the URL structurally
- Parse the value with the
URLclass. - Require
https:. - Reject embedded credentials.
- Reject fragments and unexpected ports.
- Normalize the approved API path rather than accepting arbitrary base paths.
- Parse the value with the
-
Control redirects
- Set
redirect: "manual"and reject redirects, or validate every redirect destination using the same policy before following it. - Do not rely only on validating the initial URL.
- Set
-
Block internal destinations
- Resolve the hostname and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
- Revalidate the connected destination to mitigate DNS rebinding and time-of-check/time-of-use issues.
- Explicitly block cloud metadata addresses.
-
Separate test configuration
- Permit arbitrary local endpoints only behind an explicit test-mode switch.
- Ensure production Agent invocations cannot enable test mode through untrusted input.
-
Limit request resource consumption
- Add an
AbortSignaltimeout. - Enforce a maximum response size before parsing or storing the body.
- Avoid including complete remote response bodies in error messages.
- Add an
-
Add regression tests
- Verify rejection of HTTP URLs, embedded credentials, loopback addresses, private addresses, link-local addresses, unexpected ports, and redirect chains to prohibited destinations.
-
