Back to skill

Security audit

Gitea Actions

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it handles a powerful Gitea token in ways that could expose it if configured insecurely.

Install only if you control the Gitea endpoint and can use a least-privilege token. Configure GITEA_URL with HTTPS, avoid broad account tokens, and consider rotating any token previously used with the documented HTTP-style configuration or in environments where process arguments are logged or visible.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:7
Finding
Gitea API Token Can Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:5-8`; `index.js:21-22, 30, 39-40, 56, 63` **Vulnerability Type**: Sensitive credential transmission over an unencrypted channel **Risk Level**: High ### Vulnerable Code `SKILL.md:5-8`: ```markdown ## Environment Variables - `GITEA_URL` - Gitea API URL (e.g., `http://8.137.50.76:10000`) - `GITEA_TOKEN` - Gitea API token ``` `index.js:21-22`: ```js const GITEA_URL = mustGetEnv("GITEA_URL").replace(/\/+$/, ""); const GITEA_TOKEN = mustGetEnv("GITEA_TOKEN"); ``` `index.js:30`: ```js const baseUrl = `${GITEA_URL}/api/v1/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`; ``` `index.js:39-40`: ```js "-H", `Authorization: token ${GITEA_TOKEN}`, "-H", "Content-Type: application/json", ``` The same authorization header pattern is used for the remaining API operations at `index.js:56` and `index.js:63`. ### Technical Analysis The documentation explicitly presents a plaintext `http://` Gitea URL as its configuration example. The implementation accepts the configured URL without validating its scheme and passes the API token in the HTTP `Authorization` header. When `GITEA_URL` uses HTTP, neither the credential nor the response has transport-layer confidentiality or integrity. A network-positioned attacker can read the API token, observe repository and workflow information, or alter API traffic. URL encoding of repository parameters does not mitigate transport interception. ### Attack Path 1. An operator configures `GITEA_URL` with an `http://` endpoint, potentially by following the documented example. 2. The operator invokes the skill to dispatch a workflow, list runs, or retrieve a run. 3. The skill sends `Authorization: token <GITEA_TOKEN>` to the endpoint without TLS. 4. An attacker with access to the network path captures the request and extracts the token. 5. The attacker reuses the token directly against the Gitea API. 6. The attacker obtains whatever repository and workflow ...[truncated 741 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse `GITEA_URL` with the standard `URL` class and require the `https:` protocol before sending credentials. 2. Reject `http:` endpoints by default with an explicit security error. 3. If plaintext HTTP is required for isolated local development, place it behind an explicit opt-in setting, restrict it to loopback addresses, and display a prominent warning. 4. Replace the documentation example with an HTTPS URL, such as `https://gitea.example.com`. 5. Configure strict TLS certificate validation and do not introduce options that bypass certificate verification. 6. Scope the Gitea token to only the repositories and workflow permissions required by the skill. 7. Rotate any token that may already have been used over an untrusted plaintext connection. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:39
Finding
Gitea API Token Is Exposed in the curl Process Argument Vector<![CDATA[ ## Vulnerability Details **File Location**: `index.js:8-9, 39-40, 56, 63` **Vulnerability Type**: Local credential exposure through child-process command-line arguments **Risk Level**: Medium ### Vulnerable Code `index.js:8-9`: ```js function curl(args) { return new Promise((resolve, reject) => { const p = spawn("curl", args, { env: process.env }); ``` `index.js:38-40`: ```js "-X", "POST", "-H", `Authorization: token ${GITEA_TOKEN}`, "-H", "Content-Type: application/json", ``` `index.js:56`: ```js const result = await curl(["-sS", "-H", `Authorization: token ${GITEA_TOKEN}`, url]); ``` `index.js:63`: ```js const result = await curl(["-sS", "-H", `Authorization: token ${GITEA_TOKEN}`, url]); ``` ### Technical Analysis The skill interpolates `GITEA_TOKEN` into a command-line argument passed to the spawned `curl` process. Although `spawn` is used without a shell and therefore avoids shell metacharacter interpretation, the secret remains present in the child process's argument vector. Depending on the operating system, process-isolation policy, container configuration, and monitoring environment, command-line arguments can be visible through process-listing utilities, process telemetry, audit systems, or interfaces such as `/proc/<pid>/cmdline`. The process only needs to be observed while the request is active. This issue is credential exposure rather than command injection: the array-based `spawn` invocation does not itself provide a shell injection path. ### Attack Path 1. A legitimate caller invokes any supported action. 2. The skill starts `curl` with the complete authorization header in its argument vector. 3. A local user, colocated process, container observer, or monitoring agent with sufficient process-inspection access observes the `curl` process. 4. The observer reads the command-line arguments and extracts the Gitea token. 5. The observer reuses the token against the configured Gitea instance. 6. The observer gains the repo ...[truncated 680 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the external `curl` process with Node.js's native `https` client or `fetch`, supplying the authorization token as an in-process request header. 2. Do not place secrets in executable arguments, URLs, error messages, or application logs. 3. Ensure request tracing and debug logging redact `Authorization` headers. 4. Run the skill under a dedicated, least-privileged operating-system identity and enable process-visibility restrictions where supported. 5. Scope tokens to the minimum required repositories and operations. 6. Rotate the token if process telemetry, audit logs, or monitoring systems may already have recorded command-line arguments. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This code launches an external subprocess using `spawn("curl", ...)`, which is a safety-relevant operation for code files. While there are internal comments, there is no confirmation prompt, user-facing log/print, or visible disclosure in this file warning that the skill executes shell-adjacent external commands.

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
The skill performs authenticated network operations against a Gitea instance using a token from environment variables, but no manifest or user-visible purpose is provided to justify that capability. This creates an unnecessary trust gap: a caller may trigger repository workflow dispatches or inspect workflow runs without clear disclosure, increasing the risk of unauthorized CI/CD actions or information exposure if the skill is installed in a broader agent context.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill sends an authorization token in outbound requests to a URL derived from GITEA_URL without any user-facing disclosure or destination validation. If the environment variable is misconfigured or attacker-controlled, the token could be transmitted to an unintended host, enabling repository compromise or abuse of CI/CD infrastructure.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The code reads `GITEA_URL` and `GITEA_TOKEN` from environment variables, including a credential-like token. Access to sensitive environment variables is listed as a warning-worthy operation for code files, but there is no user-facing notice or documentation in this file describing that dependency.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:11