Back to skill

Security audit

consolidate

Security checks for vulnerabilities and agentic risk

Overview

This is a real PR review-consolidation skill, but it needs Review because it can post GitHub reviews/comments, install dependencies/hooks, and contains unsafe checkout guidance for PR branch metadata.

Install only if you want an agent with GitHub write/review authority to run this workflow. Prefer explicit `/consolidate ... --interactive`, pin installation sources, review any hook registration, and avoid using it on untrusted PR branches until the documented git commands validate and quote PR branch/base refs and worktree paths.

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
pr.md:364
Finding

Command Injection Through Unquoted PR Branch Metadata

Content
View full analysis

Vulnerability Details

File Location: pr.md, lines 364–373
Vulnerability Type: Shell command injection through untrusted PR metadata
Risk Level: High

Vulnerable instructions:

bash
# Same-repository PR
git -C <worktree> fetch origin <headRefName> <baseRefName>

# Fork PR
gh pr checkout <N> -R <owner>/<repo> --force
git -C <worktree> fetch origin <baseRefName>

The surrounding procedure also directs the Agent to select or create a path under:

text
.claude/worktrees/<branch>

Technical Analysis

The Skill obtains headRefName, baseRefName, and other PR metadata from gh pr view, then instructs the Agent to substitute those values directly into Bash command text. The documented commands do not quote the substituted values, validate them with git check-ref-format, or invoke the underlying tools through an argument-safe interface.

A PR author controls the head branch name. For same-repository PRs, this value is placed directly in the git fetch command. If the worktree helper derives its path from that branch name, the same value can also flow into the unquoted git -C <worktree> argument. Git reference names can contain some characters that have special meaning to a shell, so validity as a Git ref is not equivalent to safety as unquoted shell syntax.

This is not merely a user supplying a local CLI argument to attack their own account. The value originates from another PR author and crosses from GitHub-controlled PR metadata into Bash running with the reviewer’s local permissions.

No evidence indicates that this defect was intentionally introduced as malware. It is therefore classified as a reachable coding vulnerability rather than malicious behavior.

Attack Path

  1. An attacker with permission to create a branch and open a PR in the reviewed repository creates a valid Git branch name containing shell-signific ...[truncated 1772 chars]
Remediation
View remediation

Remediation Suggestions

  1. Avoid shell-text interpolation. Invoke Git and GitHub CLI using an argument-array interface where each metadata value is passed as a separate argument.
  2. Validate every ref before use:
    bash
    git check-ref-format --branch "$head_ref"
    git check-ref-format --branch "$base_ref"
    
    Reject values that fail validation.
  3. Quote all shell expansions:
    bash
    git -C "$worktree" fetch origin "$head_ref" "$base_ref"
    
    Quoting should be mandatory in the documented procedure, not left to Agent discretion.
  4. Prefer immutable identifiers. Fetch and check out the PR’s validated headRefOid where practical instead of using the attacker-selected branch name.
  5. Do not derive filesystem paths directly from branch names. Generate a safe worktree directory from the PR number or a strict allowlisted slug, such as .claude/worktrees/pr-123.
  6. Validate repository identifiers and base refs separately. Do not assume that successful output from gh pr view makes a value safe for shell interpretation.
  7. Add a mandatory pre-execution gate that rejects newline characters, shell metacharacters, malformed refs, and paths outside the designated worktree root.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (51)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · CHANGELOG.md (reported line 128)May include surrounding context.

md
### Features

* **consolidate:** address PR 134 reviews and reflect orange/yellow severity display rules ([e6118d0](https://github.com/es6kr/skills/commit/e6118d0fb0217a4c4ad388b82e574203a8f9258e))
* **next-feat:** accumulate features for hook-kit context gate ([df4f73a](https://github.com/es6kr/skills/commit/df4f73ae4d27d4919105da70c6c94a14a32e8056))

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad workflow skill for consolidating PR/issue feedback, classifying findings, making decisions, and posting summaries/reviews. The supplied code does not implement that workflow. Instead, it is a defensive hook that monitors Bash/run_command invocations for GitHub review/comment posting and blocks them when the body format would break a downstream verifier. This is a materially different primary purpose and introduces undeclared command interception/blocking behavior. While the code is tangentially related to PR review posting, it only validates two specific formatting constraints and does not perform collection, classification, decisioning, summarization, or next-action prompting as described.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a review-consolidation workflow skill that collects, classifies, decides on, and posts review summaries. The supplied code does not implement that workflow. Instead, it is a guardrail hook that monitors Bash/run_command tool invocations, detects attempts to post PR/issue comments or reviews through gh/curl/API endpoints, inspects the proposed body content, and denies the action if it appears to be a review-like comment lacking required provenance markers. That enforcement behavior is related to the consolidate workflow, but it is a distinct primary purpose and capability: pre-execution command policy enforcement rather than review consolidation itself. The code also reads command arguments and referenced local files to inspect bodies, which is not reflected in the declared permissions/triggers. Therefore this is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description presents a broad review-consolidation workflow: collecting reviews, classifying findings, helping make decisions, and posting summaries/formal reviews. The supplied code does not implement that workflow. Instead, it is a narrowly scoped enforcement hook that monitors outgoing gh/curl posting commands and blocks them when a consolidate-style comment appears to contain fabricated factual claims. This is a materially different primary purpose and includes undeclared capabilities such as command interception/denial and repository/API fact validation. While the code relates to review-summary posting, it is only a safety guard for accuracy, not the consolidation/responding system described.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description presents a broad review-consolidation workflow for PRs/issues, including gathering reviews, classification, decision support, posting summaries, and follow-up actions. The supplied code does not implement that workflow. Instead, it performs a specific enforcement function: it examines command invocations for GitHub comment publication, extracts candidate comment bodies, looks for 'AI Review Summary' findings tables, and blocks posting if the Status column is missing or uses disallowed vocabulary. This is a materially different primary purpose and an undeclared capability (pre-execution command blocking/policy enforcement). While it relates to the 'post' stage of review summaries, the code is only a validation guard for one formatting/content rule, not the declared consolidation/responding functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The supplied code matches only a narrow subset of the declared 'collect' step: gathering PR-related review/comment/check data. However, the declared purpose describes a broader end-to-end review consolidation and response workflow across PRs/issues, including classification, decision-making, posting summaries/formal reviews, deferred handling, and next-action prompting. None of those behaviors appear in this code chunk. Additionally, the script performs undeclared checks of Copilot billing status and supports account-based token injection. The primary behavior is PR data collection/reporting, so the description materially overstates and misrepresents what this specific code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents an end-to-end workflow skill for consolidating external review feedback and producing responses/posts. The supplied code instead implements a verifier for already-posted consolidation artifacts. Its primary behavior is checking presence of specific comment types, chronology, reviewer counts, findings-table row counts, status vocabulary, and commit SHA existence using gh api and local git. That is materially different from collecting reviews, classifying findings, deciding dispositions, posting summaries/formal reviews, or asking next actions. While validation could be a supporting piece of such a system, this code chunk's actual purpose is narrowly auditing compliance, which is an undeclared capability and a different primary purpose.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 86)May include surrounding context.

md
(auto-fallback, no ask), Copilot sequential, worktree checkout, Rules | [pr.md](./pr.md) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 104)May include surrounding context.

md
(auto-fallback, no ask), Copilot sequential, worktree checkout, Rules | [pr.md](./pr.md) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 107)May include surrounding context.

md
(auto-fallback, no ask), Copilot sequential, worktree checkout, Rules | [pr.md](./pr.md) |

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document defines conflicting gates for when CodeRabbit CLI may run: earlier text says CLI is only allowed when the bot layer is empty, while the later dual-fallback gate says both superpowers and CodeRabbit CLI are mandatory when external bot review is absent or returns 0 findings. In an automation skill, contradictory control flow around review execution can cause duplicate or unauthorized review actions, inconsistent enforcement, or bypass of the intended independence checks.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
90% confidence
Finding

The skill instructs the agent to parse hidden HTML-comment metadata from local markdown files to alter runtime behavior, effectively creating covert control signals outside the visible workflow. Hidden instructions are dangerous because they make behavior hard to audit, can be manipulated by adversarial content in the recurrence store, and may steer escalation paths without transparent user awareness.

Content

Scanner excerpt · internal.md (reported line 115)May include surrounding context.

The ladder below is reactive: it says what to do after a dispatch fails. That wastes a dispatch when the failure is already known to be deterministic in this environment. Before the first dispatch, grep the recurrence store for this dispatch's failure class and read the result as a rung selector:

bash
grep -rn --include="*.md" -oE "<!-- fa: class=[a-z0-9-]*(dispatch|subagent|agent-spawn)[a-z0-9-]* count=[0-9]+[^>]*-->" \
  "${FA_DATA_DIR:-$HOME/.claude/skills/cleanup/data}"

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · post.md (reported line 207)May include surrounding context.

md
Localize the disclaimer to the repo's default language (Korean for PRIVATE Korean-default repos per opensource.md, English for PUBLIC). Omit the disclaimer when author == me (self-authored PRs — your own merge strategy is yours).

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The document first establishes a safety boundary of 'report, do not resolve' for conflicting PRs, then overrides it with an exception that instructs the operator to merge, resolve conflicts, and push updates for staging promotion PRs. That contradictory rule weakens operator safeguards and normalizes code modification in a skill that otherwise presents itself as non-mutating review consolidation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill is scoped as a review-consolidation workflow, but it authorizes the operator to perform code-changing git actions on a promotion PR branch, including conflict resolution and pushing to origin. That expands authority from analysis/reporting into modifying remote code, creating a dangerous path for unintended or unauthorized changes to another branch under the guise of review automation.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'env' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · resources/block-noncompliant-review-comment.sh (reported line 23)May include surrounding context.

sh
#   - Claude Code:  stdin {tool_name, tool_input.command}; block = exit 2 + stderr.
#   - Antigravity:  stdin {toolCall.name, toolCall.args...}; block = stdout
#                   {"decision":"deny","reason":...} (+ exit 0).
#   The same script emits BOTH so it works registered in ~/.claude/settings.json
#   AND ~/.gemini/config/hooks.json.
#
#   NOTE (unverified): the exact Antigravity run_command arg key is not confirmable

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · resources/block-noncompliant-review-comment.sh (reported line 24)May include surrounding context.

sh
#   - Antigravity:  stdin {toolCall.name, toolCall.args...}; block = stdout
#                   {"decision":"deny","reason":...} (+ exit 0).
#   The same script emits BOTH so it works registered in ~/.claude/settings.json
#   AND ~/.gemini/config/hooks.json.
#
#   NOTE (unverified): the exact Antigravity run_command arg key is not confirmable
#   from a Claude Code session. This script tries "command" / "CommandLine" and

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/collect.sh (reported line 12)May include surrounding context.

sh
PR="${2:?usage: collect.sh <repo> <pr_number> [account]}"
ACCOUNT="${3:-}"

# Inject GH_TOKEN if account is specified to work around multi-account keyring bugs
if [[ -n "$ACCOUNT" ]]; then
  echo "INFO: Pinning GitHub account: $ACCOUNT" >&2
  export GH_TOKEN="$(gh auth token --user "$ACCOUNT")"

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The README instructs users to run npx skills add ... without pinning a specific version or immutable reference. That can cause installation of whatever package/version is current at execution time, creating a supply-chain risk if the package is updated maliciously, compromised, or changed incompatibly.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

This command again relies on npx skills add ... without a pinned version, so users may fetch and execute unreviewed future code. In documentation, this is risky because readers often copy-paste commands directly, making package compromise or typo/replacement attacks more impactful.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The README recommends installing obra/superpowers via an unpinned npx workflow, which introduces non-deterministic dependency resolution and potential supply-chain exposure. Because this skill explicitly depends on external review tooling, the context increases the attack surface rather than reducing it.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

This full-plugin installation command also uses an unpinned npx reference, allowing unexpected code to be executed if upstream content changes. Since the command installs a broad plugin/dependency tree, compromise could have wider impact than a narrowly scoped install.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad and include many generic review-related terms such as 'PR review', 'review check', and 'merge ready', which can cause the skill to activate in contexts where the user did not intend this workflow. Unintended activation is dangerous here because the skill is authorized to use Bash, Edit, Write, and GitHub-related workflows, increasing the chance of accidental repository changes, comment drafting, or posting actions in the wrong context.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The meaning-based auto-activation rules are ambiguous because they instruct matching by semantic intent 'in any language' rather than deterministic tokens. This can lead to misclassification of ordinary user messages as approval to enter interactive review-post workflows, creating confusion and potentially triggering unwanted drafting, questioning, or eventual posting behavior based on a loose interpretation of user intent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.