Back to skill

Security audit

Gitea Workflow Dispatch

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it can send a Gitea API token over an unvalidated HTTP endpoint while triggering remote workflows.

Review this before installing if the configured Gitea token can deploy, publish, or access private repositories. Use only a narrowly scoped token, set GITEA_URL to HTTPS, avoid plaintext HTTP except in isolated local testing, and prefer adding HTTPS validation and a minimal subprocess environment before trusting it for sensitive workflows.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

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(/\/+$/, ""); ```
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill declares that it requires environment variables and demonstrates execution of Node.js code, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization gap where an agent may invoke shell/code capabilities and access secrets like GITEA_TOKEN without an explicit, reviewable restriction boundary, increasing the chance of unintended command execution or credential misuse.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The manifest describes an API-triggering skill for Gitea/Forgejo, which is satisfied by making an HTTP request. Importing child_process and later using it to execute curl adds process-execution capability beyond what is necessary for the stated purpose, increasing the skill's operational power relative to its declared intent.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill reads GITEA_URL and GITEA_TOKEN from environment variables and then uses them to send an authenticated POST request to a remote Gitea API. In this file there is no confirmation prompt, user-facing log/print, or comment/docstring warning that credentials will be used to trigger a remote workflow.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The code spawns an external curl subprocess to make the workflow-dispatch request, which is a safety-relevant operation under the warning criteria for code files. This file contains no user-facing notice, confirmation, or explanatory comment around executing the subprocess unless dryRun is already supplied.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The subprocess inherits the entire parent environment via `env: process.env`, unnecessarily exposing all available secrets and configuration to the child process. If `curl` is replaced, wrapped, instrumented, or influenced by environment-sensitive behavior, unrelated credentials could be accessed or leaked beyond what is needed for the workflow dispatch.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:50