Back to skill

Security audit

Manage Secrets

Security checks for vulnerabilities and agentic risk

Overview

This skill is purpose-built for managing deployment secrets, but it handles powerful credentials and user-supplied secret values in ways that need careful review before use.

Install only in a tightly controlled environment with a minimally scoped GitHub token, trusted operators, logging redaction, and workflow-side RBAC you have verified. Prefer revising the skill to avoid raw shell interpolation and avoid placing secret values directly in command-line arguments.

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:41
Finding
Shell Command Injection Through Unquoted Raw Secret Parameters<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 5 and 41–45 **Vulnerability Type**: T09: Insecure Skill Coding Practices **Risk Level**: High ### Vulnerable Code ```yaml command-arg-mode: raw ``` ```bash export GITHUB_TOKEN="$AGENT_GITHUB_PAT" gh workflow run set-secret.yml \ --repo "$MANAGE_SECRETS_GITHUB_REPO" \ -f persona=<PERSONA> \ -f secret_key=<KEY> \ -f secret_value=<VALUE> ``` ### Technical Analysis The skill uses raw command argument dispatch and instructs the agent to insert `PERSONA`, `KEY`, and `VALUE` directly into a shell command without shell-safe quoting. The secret value is inherently user-controlled because the skill exists to accept a credential supplied for storage. If the documented placeholders are replaced through direct textual interpolation, shell metacharacters in a supplied value can be interpreted by the shell rather than passed as part of a single argument. Relevant payload constructs include command substitution, command separators, redirections, and shell expansions. Validation is documented for `KEY`, but no equivalent validation or shell-safe transport is defined for `VALUE`. Quoting the repository variable does not protect the unquoted placeholders. ### Attack Path 1. An attacker or untrusted user asks the agent to set a secret containing shell syntax, such as a command substitution or command separator. 2. The agent inserts the supplied value into the documented `<VALUE>` placeholder. 3. Because `command-arg-mode` is `raw` and the resulting value is not quoted or passed through a shell-free argument interface, the local shell interprets the injected syntax. 4. The injected command executes with the permissions and environment of the agent process. 5. The malicious process may read `AGENT_GITHUB_PAT`, access files available to the agent, invoke GitHub APIs, or tamper with repositories and deployment resources accessible through existing credentials. Exploitation depends on the runtime p ...[truncated 1019 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not generate a shell command by interpolating raw values. Invoke `gh` through a structured subprocess API with an explicit argument array and with shell execution disabled. 2. If shell execution is unavoidable, pass dynamic values through positional parameters rather than embedding them into command text. Do not rely on ad hoc escaping. 3. Validate `PERSONA` and `KEY` against strict allowlists before invocation. Continue enforcing `^[A-Z][A-Z0-9_]*$` for keys and define a similarly restrictive persona format. 4. Treat `VALUE` as arbitrary binary or text data. Do not attempt to make it safe through character filtering alone, because legitimate secrets may contain shell metacharacters. 5. Replace `command-arg-mode: raw` with a structured command mode where supported. 6. Run the skill under a minimally privileged identity and use a fine-grained GitHub token limited to the required repository and workflow permissions. 7. Add regression tests using values containing spaces, quotes, semicolons, dollar signs, backticks, newlines, and command-substitution syntax. Verify that each value reaches GitHub as data and never executes locally. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:41
Finding
Plaintext Secret Exposure Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 41–45 **Vulnerability Type**: T09: Insecure Skill Coding Practices **Risk Level**: Medium ### Vulnerable Code ```bash export GITHUB_TOKEN="$AGENT_GITHUB_PAT" gh workflow run set-secret.yml \ --repo "$MANAGE_SECRETS_GITHUB_REPO" \ -f persona=<PERSONA> \ -f secret_key=<KEY> \ -f secret_value=<VALUE> ``` ### Technical Analysis The workflow command transmits the plaintext secret as the value of a command-line argument. Command-line argument vectors may be observable through process-inspection facilities, shell debugging, execution wrappers, audit systems, terminal capture, agent tool logs, or error reports. Although exposure through process listings depends on operating-system controls and process lifetime, logs and command tracing may persist the value well after the command finishes. Exporting `GITHUB_TOKEN` also places the authentication token in the child process environment, but the principal issue at this location is the explicit inclusion of the new secret in the argument vector. The skill provides no requirement to disable shell tracing, redact command output, prevent command logging, or securely remove temporary records. ### Attack Path 1. A user supplies a sensitive token, API key, or password for storage. 2. The agent invokes `gh workflow run` with the plaintext value in the `-f secret_value=<VALUE>` argument. 3. A local process observer, command wrapper, audit facility, shell trace, or agent logging component captures the process arguments or rendered command. 4. The captured value remains visible to the observer or is retained in logs. 5. The observer uses the exposed credential against the service for which it was issued. This issue does not require compromise of the encrypted `secrets.yaml`; disclosure occurs before the GitHub workflow encrypts and stores the value. ### Impact Assessment The direct impact is disclosure of any credential submitted through this sk ...[truncated 495 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid placing plaintext secrets directly in command-line arguments. 2. Prefer a supported standard-input, protected-file, or file-descriptor mechanism that does not expose the value in the process argument vector. 3. If a temporary file is unavoidable, create it with owner-only permissions, place it on an appropriate protected filesystem, avoid predictable names, and delete it immediately after use. 4. Disable shell tracing and command echoing around all secret-handling operations. 5. Configure agent, subprocess, audit, and CI logging to redact secret values and sensitive workflow inputs. 6. Ensure errors report only field names and status information, never submitted values. 7. Restrict local process inspection and execution-log access to trusted administrators. 8. Document the residual exposure characteristics of the selected GitHub CLI transport and test that secrets do not appear in process listings, terminal transcripts, or retained logs. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (6)

Credential Access

High
Category
Privilege Escalation
Content
# Manage Secrets — Self-Service Secret Updates

Trigger the `set-secret.yml` workflow in the env repo to set or update an environment secret for this persona. The workflow decrypts the SOPS-encrypted `secrets.yaml`, injects the key/value under `envSecrets`, re-encrypts, and pushes the change — which triggers a deploy.

## Required Environment Variables
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# Manage Secrets — Self-Service Secret Updates

Trigger the `set-secret.yml` workflow in the env repo to set or update an environment secret for this persona. The workflow decrypts the SOPS-encrypted `secrets.yaml`, injects the key/value under `envSecrets`, re-encrypts, and pushes the change — which triggers a deploy.

## Required Environment Variables
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# Manage Secrets — Self-Service Secret Updates

Trigger the `set-secret.yml` workflow in the env repo to set or update an environment secret for this persona. The workflow decrypts the SOPS-encrypted `secrets.yaml`, injects the key/value under `envSecrets`, re-encrypts, and pushes the change — which triggers a deploy.

## Required Environment Variables
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# Manage Secrets — Self-Service Secret Updates

Trigger the `set-secret.yml` workflow in the env repo to set or update an environment secret for this persona. The workflow decrypts the SOPS-encrypted `secrets.yaml`, injects the key/value under `envSecrets`, re-encrypts, and pushes the change — which triggers a deploy.

## Required Environment Variables
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## Required Environment Variables

- `AGENT_GITHUB_PAT` — a fine-grained PAT with Actions write permission on the env repo. There is no fallback; the PAT must be present.
- `MANAGE_SECRETS_GITHUB_REPO` — the GitHub `owner/repo` of the env repo that contains `set-secret.yml` (e.g., `myorg/myapp-env`).

```bash
if [[ -z "$AGENT_GITHUB_PAT" ]]; then
Confidence
86% confidence
Finding
The skill instructs exporting a long-lived personal access token (`AGENT_GITHUB_PAT`) into `GITHUB_TOKEN` for CLI use. This expands the token's availability to child processes and any invoked tooling, increasing the chance of accidental exposure through process inspection, shell history, debugging output, or misuse by other skills operating in the same environment.

Credential Access

High
Category
Privilege Escalation
Content
```bash
export GITHUB_TOKEN="$AGENT_GITHUB_PAT"
gh workflow run set-secret.yml \
  --repo "$MANAGE_SECRETS_GITHUB_REPO" \
  -f persona=<PERSONA> \
  -f secret_key=<KEY> \
Confidence
89% confidence
Finding
This command triggers a workflow that writes arbitrary secret key/value pairs into the environment repository using a privileged PAT. In skill context, this is sensitive because it enables modification of deployment secrets and could be abused to insert attacker-controlled credentials or service endpoints if the agent is prompted maliciously or the RBAC/workflow checks are insufficient.

Static analysis

No suspicious patterns detected.