T09 · Insecure Skill Coding Practices
- Location
actions/proxy.js:52- Finding
Unrestricted Base URL Override Exposes API Credentials and Conversation Data
- Content
View full analysis
Vulnerability Details
File Location:
actions/proxy.js:52-56, 105, 110-116
Vulnerability Type: Unvalidated outbound request destination / credential disclosure
Risk Level: HighVulnerable Code
js const baseUrl = normBase( context?.config?.ZHENINSURE_BASE_URL ?? context?.env?.ZHENINSURE_BASE_URL ?? process.env.ZHENINSURE_BASE_URL );js const url = `${baseUrl}${endpoint}`; let res; try { const ctl = new AbortController(); const timer = setTimeout(() => ctl.abort(), REQUEST_TIMEOUT_MS); res = await fetch(url, { method, headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}`, "User-Agent": `ZhenInsure-Skill/${SKILL_VERSION}`, Accept: "application/json", }, body: method === "POST" && body ? JSON.stringify(body) : undefined, signal: ctl.signal, });Technical Analysis
The proxy restricts endpoint paths and HTTP methods, but it does not restrict the destination origin.
ZHENINSURE_BASE_URLmay come from action context configuration, context environment data, or the process environment. ThenormBasefunction only trims whitespace and trailing slashes; it does not enforce HTTPS, verify the hostname, restrict ports, or require the official ZhenInsure origin.The proxy subsequently sends the live
ZHENINSURE_API_KEYin anAuthorizationheader and forwards the request body to the selected origin. Consequently, anyone able to influence the base URL can redirect credentials and insurance consultation data to an attacker-controlled server.This behavior exceeds the minimum privileges declared in
SKILL.md, which states that requests are forwarded directly tohttps://www.zhenins.com. The custom-origin behavior is explicitly covered by tests intest/test-all.js:414-462, including configuration and process-environment overrides.Attack Path
- An attacker, compromised ...[truncated 1444 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove the runtime base-URL override from production builds and always use the fixed official origin:
js const baseUrl = "https://www.zhenins.com"; -
If staging support is operationally required, parse the value with
new URL()and enforce:https:only.- An exact hostname allowlist.
- Approved ports only.
- No embedded username or password.
- No query string or fragment in the configured base URL.
- A normalized origin rather than arbitrary URL concatenation.
-
Use separate credentials for production and staging so a production key is never sent to a non-production origin.
-
Disable automatic cross-origin redirects or verify the final destination before forwarding an authorization header. Sensitive authorization headers must never be forwarded to an unapproved redirect target.
-
Ensure environment and action-context configuration cannot override the trusted destination unless controlled by an authorized administrator.
-
Add negative tests proving that the proxy rejects:
- Plaintext HTTP URLs.
- Unapproved domains.
- Look-alike and subdomain-suffix hosts.
- Embedded credentials.
- Unexpected ports.
- Redirects to unapproved origins.
-
Update the documentation to accurately disclose any approved staging behavior and its credential-separation requirements.
-
