T09 · Insecure Skill Coding Practices
- Location
scripts/rumor_scanner.py:143- Finding
Environment-Controlled API Endpoint Can Disclose the AISA API Key
- Content
View full analysis
Vulnerability Details
File Location:
scripts/rumor_scanner.py, lines 143–150 and 164–170
Vulnerability Type: Unrestricted authenticated API destination override
Risk Level: HighVulnerable Code
python def get_client() -> OpenAI: api_key = os.environ.get("AISA_API_KEY") if not api_key: print("❌ Error: AISA_API_KEY environment variable is not set.", file=sys.stderr) print(" Set it with: export AISA_API_KEY=your_key_here", file=sys.stderr) sys.exit(1) base_url = os.environ.get("AISA_BASE_URL", "https://api.aisa.one/v1") return OpenAI(api_key=api_key, base_url=base_url)The resulting client sends an authenticated request here:
python try: response = client.chat.completions.create( model=model, messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": prompt}, ], temperature=0.2, )Technical Analysis
The Skill legitimately requires
AISA_API_KEYto authenticate with its declared AISA service. However,get_client()also reads the undocumentedAISA_BASE_URLenvironment variable and accepts its value without validating the scheme, hostname, port, or trust relationship.The
OpenAIclient is initialized with both the legitimate API key and this unrestricted destination. Consequently, a process launcher, compromised parent process, poisoned execution environment, or surrounding automation capable of settingAISA_BASE_URLcan redirect the authenticated completion request to an attacker-controlled server.Sending the key to the default AISA endpoint is necessary for the declared functionality. Allowing an arbitrary destination is not required for rumor scanning and expands the Skill's trust boundary beyond minimum privilege.
Attack Path
- An attacker gains influence over the environment used to launch the Skill, such a ...[truncated 1512 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove the
AISA_BASE_URLoverride and use the declared service directly if alternate endpoints are not essential:python AISA_BASE_URL = "https://api.aisa.one/v1" return OpenAI(api_key=api_key, base_url=AISA_BASE_URL) -
If endpoint customization is a required feature, parse the URL and enforce an explicit allowlist:
- Require HTTPS.
- Permit only approved AISA hostnames.
- Reject embedded user information.
- Reject unapproved ports.
- Reject malformed URLs and IP-literal bypasses.
- Normalize and validate the hostname before comparison.
-
Prevent credentials from being forwarded across redirects to a different origin. Configure the HTTP client to reject cross-origin redirects for authenticated requests or disable redirects entirely.
-
Document any supported endpoint override in
SKILL.md, including the security implications. Require explicit user confirmation before sending credentials to any non-default approved host. -
Use a narrowly scoped, revocable API key with spending and quota limits. Rotate the key immediately if it may have been used while
AISA_BASE_URLpointed to an untrusted destination. -
Add automated tests verifying that non-HTTPS URLs, arbitrary domains, deceptive subdomains, user-info URLs, and unapproved ports are rejected before client initialization.
-
