T09 · Insecure Skill Coding Practices
- Location
scripts/gen_covers_ai.py:36- Finding
OpenRouter API Credential Is Transmitted to an Unrelated Ofox Endpoint
- Content
View full analysis
Vulnerability Details
File Location:
scripts/gen_covers_ai.py, lines 36–46
Vulnerability Type: Cross-provider credential disclosure
Risk Level: HighVulnerable Code
python def key(): k = os.environ.get("OFOX_API_KEY") or os.environ.get("OPENROUTER_API_KEY") if not k: raise SystemExit("缺 OFOX_API_KEY / OPENROUTER_API_KEY") return k def gen(prompt, out, tries=6): for t in range(1, tries+1): try: payload = json.dumps({"model": MODEL, "prompt": prompt, "size": "1024x1536", "n": 1}).encode() req = urllib.request.Request(OFOX_URL, data=payload, headers={"Authorization": f"Bearer {key()}", "Content-Type": "application/json"}) d = json.loads(urllib.request.urlopen(req, timeout=300).read())["data"][0]The destination is statically defined earlier in the same file as:
python OFOX_URL = "https://api.ofox.ai/v1/images/generations"Technical Analysis
The
key()function accepts either anOFOX_API_KEYor anOPENROUTER_API_KEY. Regardless of which credential is selected,gen()places it in a Bearer authorization header and sends it to the fixed Ofox endpoint.API credentials are ordinarily scoped to a specific provider and trust boundary. Sending an OpenRouter credential to Ofox exposes that credential to an unrelated service, including its network termination, request logging, monitoring, and operational infrastructure. The fallback does not change the endpoint to OpenRouter and does not verify that the credential belongs to the selected provider.
This is a credential-confusion flaw rather than a hardcoded-secret issue: the user supplies the secret securely through an environment variable, but the application transmits it to the wrong party.
Attack Path
- A user configures
OPENROUTER_API_KEYbut does not configureOFOX_API_KEY. - The user invokes
scripts/gen_covers_ai.py. - ` ...[truncated 961 chars]
- A user configures
- Remediation
View remediation
Remediation Suggestions
- Remove
OPENROUTER_API_KEYas a fallback when sending requests to Ofox:python def key(): value = os.environ.get("OFOX_API_KEY") if not value: raise SystemExit("OFOX_API_KEY is required") return value - If both providers are intended to be supported, bind each endpoint to its own credential:
python PROVIDERS = { "ofox": { "url": "https://api.ofox.ai/v1/images/generations", "env": "OFOX_API_KEY", }, "openrouter": { "url": "https://openrouter.ai/api/v1/...", "env": "OPENROUTER_API_KEY", }, } - Require an explicit provider selection rather than silently falling back between credentials.
- Validate that the selected endpoint host matches an allowlist for the selected provider before attaching the authorization header.
- Update the documentation so it does not imply that an OpenRouter credential is valid for Ofox.
- Advise users who previously ran the script with only
OPENROUTER_API_KEYconfigured to revoke and rotate that key, then review provider usage and billing logs for unauthorized activity.
- Remove
