T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:119
- Finding
- Unvalidated OAuth Callback URL Forwarded Through a Shell Command<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 119-127 **Vulnerability Type**: Command injection and unintended loopback request **Risk Level**: High ### Vulnerable Code ```markdown 4. The user sends back something like: `http://127.0.0.1:PORT/callback?code=...&state=...` 5. Forward it to the waiting server with curl: ```bash curl -s "http://127.0.0.1:PORT/callback?code=...&state=..." ``` 6. The tool receives the code, exchanges it for a token, and completes authorization. ``` ### Technical Analysis The skill instructs the agent to receive an OAuth callback URL from the user and forward it using `curl`. It does not require the agent to validate the URL against the callback endpoint generated by the active OAuth process. If the agent constructs a shell command by directly interpolating the supplied URL, shell metacharacters—particularly an embedded double quote followed by shell syntax—could terminate the quoted argument and inject another command. Quoting the complete URL is not sufficient if untrusted input can itself contain quote characters. Even where the tool invocation does not use a shell, accepting an arbitrary URL without verifying its scheme, host, port, and path could allow requests to unrelated services listening on the server's loopback interface. The instructions also do not require validation of the OAuth `state` value before relaying the callback. ### Attack Path 1. The agent starts an OAuth CLI that waits on a loopback callback endpoint. 2. The agent asks the user to return the failed redirect URL. 3. An attacker or untrusted user supplies a crafted URL containing shell syntax, or a URL targeting a different loopback service. 4. The agent substitutes the supplied string into the documented `curl` command. 5. If the command is evaluated by a shell, injected syntax can execute with the privileges of the agent process. Otherwise, `curl` may send a request to an unintended local service. 6. The injected c ...[truncated 785 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the callback as a URL rather than treating it as an opaque shell string. 2. Compare it with callback data recorded from the active OAuth process: - Require the `http` scheme unless the tool explicitly uses another expected scheme. - Allow only an exact loopback hostname such as `127.0.0.1` or `localhost`. - Require the exact callback port and path printed or opened by the active CLI. - Reject embedded credentials, fragments, malformed encoding, control characters, and unexpected parameters. 3. Verify that the returned OAuth `state` exactly matches the state associated with the active authorization attempt. 4. Invoke `curl` through a structured argument array without a shell. Do not concatenate user-controlled input into a command string. 5. Prefer extracting validated `code` and `state` values and reconstructing the callback URL from trusted endpoint components. 6. Display the parsed destination to the user and require confirmation if it differs from the callback endpoint expected by the active process. 7. Add explicit instructions never to forward callbacks to arbitrary loopback ports or paths. ]]>
