T09 · Insecure Skill Coding Practices
Error
- Location
- governed_agents/openclaw_wrapper.py:392
- Finding
- Authentication Token Disclosure to an Arbitrary HTTP Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `governed_agents/openclaw_wrapper.py:392-436` **Vulnerability Type**: Credential disclosure through an unrestricted outbound request **Risk Level**: Critical ### Vulnerable Code ```python def spawn_governed_http( contract: TaskContract, endpoint: str = "http://localhost:3010/api/governed/spawn", auth_token: Optional[str] = None, db_path: Optional[str] = None, ) -> TaskResult: import urllib.request import urllib.error if auth_token is None: auth_token = os.environ.get("GOVERNED_AUTH_TOKEN") or os.environ.get("AUTH_TOKEN") if not auth_token: # Fallback: look for .env in OPENCLAW_WORKSPACE/command-center/ env_path = WORKSPACE / "command-center" / ".env" if env_path.exists(): for line in env_path.read_text().splitlines(): line = line.strip() if line.startswith(("API_TOKEN=", "CC_AUTH_TOKEN=", "AUTH_TOKEN=")): auth_token = line.split("=", 1)[1].strip().strip('"').strip("'") break payload = json.dumps({ "objective": contract.objective, "acceptance_criteria": contract.acceptance_criteria, "required_files": contract.required_files, "model": "Codex", "timeout_seconds": contract.timeout_seconds, "agent_id": "main", }).encode() headers = {"Content-Type": "application/json"} if auth_token: headers["Authorization"] = f"Bearer {auth_token}" try: req = urllib.request.Request(endpoint, data=payload, headers=headers, method="POST") with urllib.request.urlopen(req, timeout=contract.timeout_seconds + 60) as resp: data = json.loads(resp.read()) ``` ### Technical Analysis The function accepts a caller-controlled `endpoint` without enforcing an allowed hostname, loopback-only policy, trusted origin, or HTTPS requirement. At the same time, ...[truncated 1551 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not automatically load credentials when the endpoint is caller-controlled. - Bind credentials to a configured, trusted origin and reject all other destinations. - Default to an explicit loopback allowlist such as `localhost`, `127.0.0.1`, and `[::1]`. - Require HTTPS for any explicitly authorized non-loopback endpoint. - Compare the normalized scheme, hostname, and port against a strict allowlist. - Disable automatic redirects or validate every redirect destination before forwarding credentials. - Strip `Authorization` on cross-origin redirects. - Remove the `.env` fallback where possible and require explicit secret injection by the trusted caller. - Avoid sending task data that is not required by the remote API. - Add regression tests confirming that credentials are never sent to untrusted hosts or redirected origins. ]]>
