T09 · Insecure Skill Coding Practices
- Location
scripts/generate_image.py:161- Finding
Independent Endpoint and Credential Resolution Can Disclose API Keys
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate_image.py:161-200
Vulnerability Type: Credential-to-endpoint confusion
Risk Level: HighVulnerable Code
python provider_defaults = load_openclaw_provider_defaults() base_url = (os.getenv("IMAGE_GEN_BASE_URL") or os.getenv("OTCBOT_BASE_URL") or os.getenv("CPA_BASE_URL") or os.getenv("OPENAI_BASE_URL") or provider_defaults["base_url"] or "").rstrip("/") api_key = os.getenv("IMAGE_GEN_KEY") or os.getenv("OTCBOT_API_KEY") or os.getenv("CPA_API_KEY") or os.getenv("OPENAI_API_KEY") or provider_defaults["api_key"] or "" user_agent = os.getenv("CPA_USER_AGENT", "codex-tui/0.122.0 (Manjaro 26.1.0-pre; x86_64) vscode/3.0.12 (codex-tui; 0.122.0)") version = os.getenv("CPA_VERSION", "0.122.0") originator = os.getenv("CPA_ORIGINATOR", "codex_cli_rs") if not base_url: fail("Missing OTCBOT_BASE_URL / CPA_BASE_URL / OPENAI_BASE_URL and no otcbot baseUrl found in models.json") if not api_key: fail("Missing OTCBOT_API_KEY / CPA_API_KEY / OPENAI_API_KEY and no otcbot apiKey found in models.json") url = f"{base_url}/responses" if base_url.endswith("/v1") else f"{base_url}/v1/responses" payload = { "model": args.model, "input": args.prompt, "tools": [ { "type": "image_generation", "output_format": args.format, } ], "instructions": args.instructions, "tool_choice": "auto", "stream": args.stream, "store": False, } last_raw = "" last_parsed = None for attempt in range(args.retries + 1): data = json.dumps(payload).encode("utf-8") req = urllib.request.Request( url, data=data, headers={ "Authorization": f"Bearer {api_key}", "user-agent": user_agent, "version": version, "originator": originator, "session_id": args.session_id, "accept": "text/ ...[truncated 2054 chars]- Remediation
View remediation
Remediation Suggestions
- Resolve endpoint and credential values as atomic provider configurations rather than through independent fallback chains.
- If
IMAGE_GEN_BASE_URLis set, requireIMAGE_GEN_KEYexplicitly and refuse to fall back to another provider's credential. - Apply the same pairing rule to
OTCBOT_BASE_URLandOTCBOT_API_KEY,CPA_BASE_URLandCPA_API_KEY, andOPENAI_BASE_URLandOPENAI_API_KEY. - Require HTTPS for non-loopback endpoints.
- Optionally maintain an allowlist of trusted endpoint origins and require explicit confirmation before sending credentials to a new origin.
- Do not automatically send a credential read from
models.jsonwhen any environment variable overrides the configured provider URL. - Add tests covering mixed configurations to verify that a URL from one provider can never receive another provider's credential.
