T09 · Insecure Skill Coding Practices
- Location
scripts/virse_call.py:25- Finding
Bearer Token Disclosure Through an Unrestricted Configurable API Endpoint
- Content
View full analysis
Vulnerability Details
File Location:
scripts/virse_call.py:25-38, 116-124
Vulnerability Type: Credential disclosure through an untrusted network destination
Risk Level: HighVulnerable Code
python def _read_token(): """Read token: VIRSE_API_KEY env > ~/.virse/token file.""" token = os.environ.get("VIRSE_API_KEY", "").strip() if token: return token try: with open(TOKEN_PATH, "r") as f: return f.read().strip() except FileNotFoundError: return "" def _base_url(): return os.environ.get("VIRSE_BASE_URL", DEFAULT_BASE_URL).rstrip("/")python def call_tool(name, args_json): base = _base_url() token = _read_token() endpoint = f"{base}/mcp" headers = {"Content-Type": "application/json", "Accept": "application/json, text/event-stream;q=0.9"} if token: headers["Authorization"] = f"Bearer {token}"The same credential-forwarding behavior appears in
batch_callat lines 169-177 andlist_toolsat lines 233-241.Technical Analysis
The script reads a sensitive Virse bearer token from either
VIRSE_API_KEYor~/.virse/token. Independently, it accepts the API destination from the unrestrictedVIRSE_BASE_URLenvironment variable. It then attaches the token as anAuthorizationheader to requests sent to that destination.The destination is not validated against an approved hostname, HTTPS is not enforced, and no restriction prevents an attacker-controlled origin from being selected. Consequently, any process, wrapper, CI configuration, or execution environment capable of influencing
VIRSE_BASE_URLcan redirect authenticated requests and capture the bearer token.Network transmission of a token to the default Virse endpoint is necessary for the Skill's declared cloud functionality. Allowing that credential to be forwarded to an arbitrary endpoint is not necessary and exceeds minimum privilege. No hardcoded malicious endpoint was identi ...[truncated 1487 chars]
- Remediation
View remediation
Remediation Suggestions
-
Restrict authenticated destinations
- Parse the configured URL with
urllib.parse.urlsplit. - Require the
httpsscheme. - Permit bearer-token transmission only to an explicit hostname allowlist, such as
dev.virse.ai. - Reject embedded credentials, fragments, unexpected ports, malformed hosts, and ambiguous URLs.
- Parse the configured URL with
-
Separate production and development credentials
- If custom endpoints are required, require a separate development credential.
- Never forward a production Virse token to a custom endpoint.
- Require an explicit, clearly named opt-in for custom endpoints.
-
Harden redirect handling
- Disable redirects for authenticated API requests or validate every redirect target.
- Strip the
Authorizationheader whenever the destination origin changes. - Reject HTTPS-to-HTTP redirects.
-
Fail closed
- Abort before reading or attaching the token when endpoint validation fails.
- Emit a clear error without printing the credential.
- Apply the same centralized validation to
call_tool,batch_call,list_tools, and OAuth endpoints.
-
Update documentation
- Clearly warn that
VIRSE_BASE_URLmust not designate an untrusted service. - Prefer removing the override from ordinary user-facing authentication instructions unless it is operationally required.
- Clearly warn that
-
Add security tests
- Verify that HTTP endpoints are rejected.
- Verify that non-allowlisted hosts do not receive authorization headers.
- Verify that cross-origin redirects cannot receive credentials.
- Verify that the default approved endpoint continues to work.
-
