Back to skill

Security audit

GitHub Issues Auto-Fix

Security checks for vulnerabilities and agentic risk

Overview

This skill automates real GitHub repository changes but handles tokens unsafely and lets external issue or review text drive privileged agents.

Review before installing. Use only with a narrowly scoped, revocable GitHub token and trusted repositories, avoid --yes/--cron on untrusted issue trackers, and do not run until token printing, token-bearing git remotes, and global git config changes are removed.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:348
Finding
Untrusted GitHub Content Is Injected into Privileged Sub-Agent Prompts<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:348-388`, `SKILL.md:676-712`, and `SKILL.md:728-830` **Vulnerability Type**: Prompt injection through untrusted GitHub issue and review content **Risk Level**: High ### Vulnerable Code ```text For each issue, construct the following prompt and pass it to sessions_spawn. Variables to inject into the template: - {SOURCE_REPO} — upstream repo where the issue lives - {PUSH_REPO} — repo to push branches to (same as SOURCE_REPO unless fork mode) - {FORK_MODE} — true/false - {PUSH_REMOTE} — `fork` if FORK_MODE, otherwise `origin` - {number}, {title}, {url}, {labels}, {body} — from the issue - {BASE_BRANCH} — from Phase 4 - {notify_channel} — Telegram channel ID for notifications (empty if not set). When constructing the task, replace all template variables including {notify_channel} with actual values. <issue> Repository: {SOURCE_REPO} Issue: #{number} Title: {title} URL: {url} Labels: {labels} Body: {body} </issue> <instructions> Follow these steps in order. If any step fails, report the failure and stop. ``` Review comments are similarly passed directly to a command-capable agent: ```text <review_comments> {json_array_of_actionable_comments} Each comment has: - id: comment ID (for replying) - user: who left it - body: the comment text - path: file path (for inline comments) - line: line number (for inline comments) - diff_hunk: surrounding diff context (for inline comments) - source: where the comment came from (review, inline, pr_body, greptile, etc.) </review_comments> <instructions> Follow these steps in order: 1. CHECKOUT — Switch to the PR branch: git fetch {PUSH_REMOTE} {branch_name} git checkout {branch_name} git pull {PUSH_REMOTE} {branch_name} 2. UNDERSTAND — Read ALL review comments carefully. Group them by file. Understand what each reviewer is asking for. 3. IMPLEMENT — For each comment, make the requested change: - Read the file and locate the relevant code - Make the change the ...[truncated 3136 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every GitHub field as untrusted data and state this explicitly in the system-controlled portion of each sub-agent prompt. 2. Do not interpolate raw issue or review content into an instruction template. Serialize it as JSON with correct escaping and process it through a dedicated data channel where available. 3. Add an immutable rule that commands, URLs, code blocks, and instructions found in issues or comments must never be executed or followed. 4. Extract a bounded problem statement using a non-tool-enabled parser before invoking a command-capable agent. 5. Run sub-agents in isolated worktrees or containers that do not contain unrelated credentials or files. 6. Provide agents with short-lived, repository-scoped credentials instead of the orchestrator's general token. 7. Apply command and path allowlists. Block access to configuration, credential, state, SSH, cloud, and unrelated repository paths. 8. Require human approval after displaying the proposed diff and before any commit, push, API write, or external notification. 9. Validate that changed files are relevant to the selected issue or review. Reject unexpected binaries, workflows, dependency changes, credential files, and unrelated modifications. 10. Disable unattended processing of content from untrusted authors, particularly in `--yes`, `--cron`, and automated review modes. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:89
Finding
GitHub Token Is Printed into Retained Execution Output<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:89-92`, `SKILL.md:393-406`, `SKILL.md:516-520`, and `SKILL.md:765-771` **Vulnerability Type**: Plaintext credential exposure through logs and retained sub-agent transcripts **Risk Level**: High ### Vulnerable Code The orchestrator explicitly prints the complete token: ```sh First, ensure GH_TOKEN is available. Check environment: echo $GH_TOKEN ``` Spawned agents print a token prefix: ```sh export GH_TOKEN=$(node -e "const fs=require('fs'); const c=JSON.parse(fs.readFileSync('/data/.clawdbot/openclaw.json','utf8')); console.log(c.skills?.entries?.['gh-issues']?.apiKey || '')") ``` ```sh If that fails, also try: export CONFIG_PATH="${OPENCLAW_CONFIG_PATH:-${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/openclaw.json}" export GH_TOKEN=$(cat "$CONFIG_PATH" 2>/dev/null | node -e "const fs=require('fs');const d=JSON.parse(fs.readFileSync(0,'utf8'));console.log(d.skills?.entries?.['gh-issues']?.apiKey||'')") ``` ```sh Verify: echo "Token: ${GH_TOKEN:0:10}..." ``` The associated sub-agent records are deliberately preserved: ```text ### Spawn configuration per sub-agent: - runTimeoutSeconds: 3600 (60 minutes) - cleanup: "keep" (preserve transcripts for review) ``` ### Technical Analysis `echo $GH_TOKEN` writes the entire GitHub bearer token to standard output. The prefix verification command also discloses ten token characters without a functional need. Command output is commonly captured by agent execution logs, orchestration telemetry, terminal history, debugging systems, and retained transcripts. This risk is amplified by `cleanup: "keep"`, which intentionally preserves sub-agent transcripts. Access controls for those records may differ from controls protecting the original secret store. A secret that was initially confined to an environment variable or configuration file therefore becomes duplicated into persistent operational records. Checking whether a secret exists does not require printing any ...[truncated 1199 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace all token-printing checks with a boolean presence check: ```sh if [ -z "${GH_TOKEN:-}" ]; then echo "GH_TOKEN is not configured" >&2 exit 1 fi ``` 2. Remove `echo $GH_TOKEN` and `echo "Token: ${GH_TOKEN:0:10}..."` entirely. 3. Configure the execution framework to redact `GH_TOKEN`, authorization headers, and token-bearing URLs from command output. 4. Ensure shell tracing is disabled while handling credentials: ```sh set +x ``` 5. Avoid retaining secret-bearing transcripts. Apply short retention periods and strict access controls to necessary diagnostic records. 6. Rotate the affected token if the Skill has already been run and its output may have been retained. 7. Prefer short-lived, repository-scoped tokens with only the API permissions required for the selected operation. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:447
Finding
GitHub Token Is Persisted in Git Remote Configuration and Global Credential Settings Are Modified<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:447-450` and `SKILL.md:797-799` **Vulnerability Type**: Persistent plaintext credential storage and excessive global configuration modification **Risk Level**: High ### Vulnerable Code ```sh First, ensure the push remote uses token auth and disable credential helpers: git config --global credential.helper "" git remote set-url {PUSH_REMOTE} https://x-access-token:$GH_TOKEN@github.com/{PUSH_REPO}.git Then push: GIT_ASKPASS=true git push -u {PUSH_REMOTE} fix/issue-{number} ``` The review handler repeats the same behavior: ```sh git config --global credential.helper "" git remote set-url {PUSH_REMOTE} https://x-access-token:$GH_TOKEN@github.com/{PUSH_REPO}.git GIT_ASKPASS=true git push {PUSH_REMOTE} {branch_name} ``` A similar token-bearing remote is created during fork setup: ```sh git remote add fork https://x-access-token:$GH_TOKEN@github.com/{PUSH_REPO}.git ``` ### Technical Analysis Embedding `GH_TOKEN` in an HTTPS remote URL stores the credential in the repository's `.git/config`. The token may remain there after the push and after the Skill terminates. It can subsequently be exposed through: - `git remote -v` and related diagnostics. - Copies or archives that include `.git`. - Support bundles and agent transcripts. - Processes or users able to inspect repository metadata. - Error messages that render the remote URL. `GIT_ASKPASS=true` does not mitigate this exposure because Git reads the credential directly from the remote URL. The command `git config --global credential.helper ""` modifies user-wide Git behavior. It is not limited to the current repository or Skill execution and is not restored afterward. This exceeds the minimum privileges needed to push one branch and can disrupt authentication for unrelated repositories and future sessions. ### Attack Path 1. The Skill resolves the GitHub token from the environment or configuration. 2. It writes the token into the `origin` or `f ...[truncated 1067 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not place credentials in remote URLs. 2. Use a temporary `GIT_ASKPASS` program that returns the token at runtime, restrict its permissions, and delete it immediately after use. 3. Alternatively, supply a temporary per-command authorization header supported by Git: ```sh git -c http.https://github.com/.extraheader="AUTHORIZATION: basic <temporary-value>" \ push -u "$PUSH_REMOTE" "$BRANCH" ``` The header value must still be generated and handled without logging. 4. Preserve credential helpers. If an override is essential, use a command-scoped setting rather than `--global`: ```sh git -c credential.helper= push ... ``` 5. Keep the stored remote URL credential-free: ```sh https://github.com/owner/repository.git ``` 6. If a remote must be changed temporarily, record its original value and restore it in a guaranteed cleanup handler: ```sh original_url="$(git remote get-url "$PUSH_REMOTE")" trap 'git remote set-url "$PUSH_REMOTE" "$original_url"' EXIT ``` 7. Audit existing working copies for token-bearing remote URLs, remove those credentials, and rotate any token that may have been persisted. 8. Run the Skill under a dedicated account with repository-local configuration and narrowly scoped, short-lived credentials. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (27)

Ssd 3

High
Confidence
100% confidence
Finding
The sub-agent prompt explicitly instructs reading a stored GitHub token from `/data/.clawdbot/openclaw.json` or other config files and then revealing part of it in output. This combines secret harvesting from local storage with disclosure into agent-visible transcripts, making credential compromise highly plausible and severe, especially since the token grants repository access and can be reused outside the session.

Ssd 3

High
Confidence
100% confidence
Finding
The review-handler sub-agent has the same secret-harvesting and partial-disclosure behavior as the implementation sub-agent. In a workflow that automatically reacts to external PR comments, this is especially dangerous because adversarial repository content could influence what gets logged or transmitted during an already privileged operation.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The top-level documentation states 'No `gh` CLI dependency' and says the skill uses 'curl + the GitHub REST API exclusively.' However, later phases instruct the agent to run multiple git commands for branch management and to use `node` to read config files for GH_TOKEN resolution. This is an active contradiction in the skill's own documentation about how it operates.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| --watch | false | Keep polling for new issues and PR reviews after each batch |
| --interval | 5 | Minutes between polls (only with `--watch`) |
| --dry-run | false | Fetch and display only — no sub-agents |
| --yes | false | Skip confirmation and auto-process all filtered issues |
| --reviews-only | false | Skip issue processing (Phases 2-5). Only run Phase 6 — check open PRs for review comments and address them. |
| --cron | false | Cron-safe mode: fetch issues and spawn sub-agents, exit without waiting for results. |
| --model | _(none)_ | Model to use for sub-agents (e.g. `glm-5`, `zai/glm-5`). If not specified, uses the agent's default model. |
Confidence
91% confidence
Finding
Advertising a flag that skips confirmation is itself part of an autonomous workflow that can make repository changes based on external issue content. In this skill, that autonomy is security-relevant because it combines with token access, git push capability, and sub-agent execution.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**If `--cron` is set:**

- Force `--yes` (skip confirmation)
- If `--reviews-only` is also set, run token resolution then jump to Phase 6 (cron review mode)
- Otherwise, proceed normally through Phases 2-5 with cron-mode behavior active
Confidence
94% confidence
Finding
Cron mode forcibly enables `--yes` and then spawns fix agents without waiting for user review, enabling unattended repository modifications driven by remote issue and review content. This is more dangerous than interactive auto-confirm because it is scheduled, persistent, and designed to operate without live oversight.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The skill broadens secret access by reading GH_TOKEN not only from the injected environment but also from local OpenClaw config files and a global bot path. That unnecessarily expands the secret retrieval surface and allows the skill or spawned sub-agents to harvest credentials from persistent storage, which is dangerous in an agent context where prompts and downstream outputs may be adversarial.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```
curl -s -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{SOURCE_REPO}/issues?per_page={limit}&state={state}&{query_params}"
```

Where {query_params} is built from:
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
If `--yes` is active:

- Display the table for visibility
- Auto-process ALL listed issues without asking for confirmation
- Proceed directly to Phase 4

Otherwise:
Confidence
92% confidence
Finding
The `--yes` mode allows the skill to automatically process and act on all fetched issues without human confirmation, leading to autonomous code changes, branch pushes, and PR creation. In a system that consumes untrusted issue content and spawns privileged sub-agents, this materially increases the chance of unsafe or attacker-influenced repository modifications.

Session Persistence

Medium
Category
Rogue Agent
Content
If output is non-empty, warn the user:

   > "Working tree has uncommitted changes. Sub-agents will create branches from HEAD — uncommitted changes will NOT be included. Continue?"
   > Wait for confirmation. If declined, stop.

2. **Record base branch:**
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
4. **Verify GH_TOKEN validity:**

   ```
   curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $GH_TOKEN" https://api.github.com/user
   ```

   If HTTP status is not 200, stop with:
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The sub-agent is instructed to print a visible prefix of GH_TOKEN (`Token: ${GH_TOKEN:0:10}...`), which is direct secret disclosure. Even partial token leakage materially weakens credential secrecy, can aid correlation across logs/transcripts, and is especially risky because transcripts are preserved with `cleanup: "keep"`.

External Transmission

Medium
Category
Data Exfiltration
Content
- base = "{BASE_BRANCH}"
- PR is created on {SOURCE_REPO}

curl -s -X POST \
  -H "Authorization: Bearer $GH_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/{SOURCE_REPO}/pulls \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The review-handler prompt repeats the same pattern of exposing the first part of GH_TOKEN in output. Because these review sub-agents also preserve transcripts, this creates durable credential leakage into logs and review artifacts.

Static analysis

No suspicious patterns detected.