T09 · Insecure Skill Coding Practices
Error
- Location
- index.js:19
- Finding
- API Token May Be Transmitted over Plaintext HTTP## Vulnerability Details **File Location**: `index.js:19-20, 41-46`; related insecure configuration example at `SKILL.md:15-18` **Vulnerability Type**: Plaintext transmission of sensitive credentials **Risk Level**: High ### Vulnerable Code `index.js:19-20`: ```js const url = `${GITEA_URL}/api/v1/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}` + `/actions/workflows/${encodeURIComponent(workflow)}/dispatches`; ``` `index.js:41-46`: ```js const args = [ "-sS", "-o", "-", "-w", "\n%{http_code}", "-X", "POST", "-H", `Authorization: token ${GITEA_TOKEN}`, "-H", "Content-Type: application/json", url, "-d", body ]; ``` `SKILL.md:15-18`: ```markdown ## Environment Variables - `GITEA_URL` - Gitea API URL (e.g., `http://8.137.50.76:10000`) - `GITEA_TOKEN` - Gitea API token ``` ### Technical Analysis The skill accepts `GITEA_URL` without parsing or validating its protocol and then sends `GITEA_TOKEN` in an HTTP `Authorization` header. The documentation explicitly gives a plaintext `http://` endpoint as its example. When an HTTP URL is configured, TLS provides neither encryption nor server authentication. The bearer-like API token, workflow reference, workflow inputs, repository identity, and server response therefore travel across the network in plaintext. Encoding repository path segments does not mitigate transport-layer interception. An attacker able to observe or manipulate traffic between the host and the configured Gitea/Forgejo server could capture the token or alter the workflow-dispatch request. ### Attack Path 1. An operator follows the documented example or otherwise configures `GITEA_URL` with an `http://` URL. 2. The skill constructs the dispatch endpoint directly from that URL without rejecting the insecure scheme. 3. The skill invokes `curl` and supplies `Authorization: token ${GITEA_TOKEN}`. 4. A network-positioned attacker mon ...[truncated 1045 chars]
- Remediation
- ## Remediation Suggestions 1. Parse `GITEA_URL` with the standard `URL` class and reject every scheme other than `https:` before constructing or sending the request. 2. If plaintext HTTP is required for isolated local development, permit it only through an explicit opt-in setting and restrict it to loopback addresses where practical. Emit a prominent warning and never enable this behavior by default. 3. Replace the HTTP example in `SKILL.md` with an HTTPS endpoint and document TLS as mandatory for token-authenticated requests. 4. Use a narrowly scoped service token that can only dispatch the required workflows in the required repositories. 5. Rotate any token that may already have been transmitted over an untrusted plaintext connection. 6. Configure trusted certificate validation for private Gitea deployments rather than disabling TLS verification. 7. Add automated tests confirming that `http:`, `ftp:`, malformed URLs, and other unsupported schemes are rejected before `curl` is spawned. Example validation: ```js const endpoint = new URL(mustGetEnv("GITEA_URL")); if (endpoint.protocol !== "https:") { throw new Error("GITEA_URL must use HTTPS"); } const GITEA_URL = endpoint.href.replace(/\/+$/, ""); ```
