Back to skill

Security audit

Smart PR Review

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent PR review skill, but its optional webhook service can automatically use GitHub and Anthropic credentials in ways that need review before installation.

Install only if you are comfortable with a self-hosted webhook service sending PR content to Anthropic and posting reviews to GitHub. Use least-privilege GitHub credentials, require a non-empty webhook secret, avoid counting bot approvals as human approval, add rate limits/body limits before exposing it publicly, and pin dependencies before deployment.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
index.ts:623
Finding

Webhook Authentication Fails Open When the Shared Secret Is Missing

Content
View full analysis
{ console.error("[Webhook] 审查处理失败:", error); }); ``` The flaw does not directly disclose the GitHub or Anthropic token. It does, however, let an unauthenticated party trigger privileged operations performed with those credentials. ### Attack Path 1. The service is deployed without `GITHUB_WEBHOOK_SECRET`, or the variable is accidentally empty. 2. An attacker submits an unsigned `POST /webhook/github` request. 3. The attacker supplies `x-github-event: pull_request` and a forged JSON payload using a supported action such as `opened`. 4. The payload names a repository and pull request accessible to the configured GitHub token. 5. The service ...[truncated 776 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
index.ts:343
Finding

Untrusted Pull Request Content Can Inject Model Instructions and Manipulate Review Verdicts

Content
View full analysis
注意: 这是大 PR 的第 ${chunkInfo.index + 1}/${chunkInfo.total} 片审查。请只审查当前片段的代码。` : ""; return ` 你是一个有立场的资深 Code Reviewer。请按照 Smart PR Review 标准审查以下变更。 ${langInstruction}${focusInstruction}${strictInstruction}${chunkNote} ## PR 信息 - **标题**: ${prTitle} - **描述**: ${prBody ?? "(无描述)"} ## 变更内容 (Diff) \`\`\`diff ${diff} \`\`\` ## 审查要求 1. 按六层审查维度逐一检查 2. 执行 Devil's Advocate 思考 3. 用标准格式输出(MUST FIX / SHOULD FIX / SUGGESTION / What's Good / Verdict) 4. 引用具体行号和代码片段 5. 对 MUST FIX 问题必须给出替代方案代码 6. 不做橡皮图章 — 有问题就直说 `.trim(); } ``` The combined prompt is sent as a single user message: ```typescript messages: [{ role: "user", content: prompt }], ``` The resulting free-form text controls the GitHub verdict: ```typescript function extractVerdict(reviewBody: string): "APPROVE" | "REQUEST_CHANGES" | "COMMENT" { const mustFixMatch = reviewBody.match(/MUST FIX \((\d+)/); if (mustFixMatch && parseInt(mustFixMatch[1], 10) > 0) { return "REQUEST_CHANGES"; } if (/\[x\]\s*REQUEST.?CHANGES/i.test(reviewBody)) { return "REQUEST_CHANGES"; } if (/\[x\]\s*APPROVE/i.test(reviewBody)) { return "APPROVE"; } return "COMME ...[truncated 2013 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
index.ts:283
Finding

Unbounded Webhook and Diff Processing Enables Denial of Service and API Cost Amplification

Content
View full analysis
maxChunkSize) { // 先把当前积累的文件打包 if (currentFiles.length > 0) { chunks.push({ files: currentFiles, totalSize: currentSize, chunkIndex: chunks.length, totalChunks: 0, // 最后回填 }); currentFiles = []; currentSize = 0; } chunks.push({ files: [file], totalSize: patchSize, chunkIndex: chunks.length, totalChunks: 0, }); continue; } ``` The code subsequently performs one Anthropic request for every generated chunk: ```typescript for (let i = 0; i < prompts.length; i++) { const prompt = prompts[i]; const response = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey, "anthropic-version": "2023-06-01", }, body: JSON.stringify({ model, max_tokens: maxTokens, messages: [{ role: "user", content: prompt }], }), }); } ``` ### Technical Analysis `MAX_DIFF_SIZE` is treated as a grouping threshold, not a hard size limit. If one file's patch exceeds the configured threshold, the entire oversized patch is placed into a standalone chunk and sent to Anthropic. The implementation also lacks hard limits for: - Incoming webhook-body size. - Number of changed files. - GitHub pagination depth. - Total diff bytes. - Number of generated chunks. - Number of model calls per webhook or repository. - Duplicate webhook deliveries. - Outbound request duration. The webhook responds with `202` before processing completes and starts work directly in the server process. Repeated events can therefore create many concurrent background tasks without queue backpressure. ### Attack Path 1. An attacker submits a very large pull request or repeatedly updates a pull request in a monitored rep ...[truncated 1148 chars]
Remediation
View remediation
maxChunkSize) { throw new Error(`Patch exceeds the maximum review size: ${file.filename}`); } ``` 3. Add independent limits for total diff bytes, changed files, GitHub pages, chunks, and model calls per delivery. 4. Deduplicate events using `x-github-delivery` and persist processed delivery identifiers for an appropriate retention period. 5. Add per-repository and per-installation rate limits. 6. Move review execution to a bounded queue with concurrency limits, backpressure, cancellation, and retry limits. 7. Configure timeouts with `AbortController` for GitHub and Anthropic requests. 8. Apply budget controls and alerting for Anthropic usage. 9. Return a safe partial-review comment when configured limits are exceeded rather than processing unlimited input. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:88
Finding

Deployment Instructions Install and Execute Unpinned Registry Packages

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill is presented as a PR review helper, but it also documents an automated webhook service that receives GitHub events, sends PR content to Anthropic, and posts results back to GitHub using repository-scoped credentials. This capability expansion is security-relevant because it changes the trust boundary, introduces external data exfiltration and token use, and is not clearly declared in the top-level purpose/permissions model.

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 500)May include surrounding context.

md
本 skill 附带 `index.ts`,提供 GitHub Webhook 自动审查能力。当 PR 被创建或更新时自动触发审查,审查结果直接发布为 GitHub PR Review 评论。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
本 skill 附带 `index.ts`,提供 GitHub Webhook 自动审查能力。当 PR 被创建或更新时自动触发审查,审查结果直接发布为 GitHub PR Review 评论。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
本 skill 附带 `index.ts`,提供 GitHub Webhook 自动审查能力。当 PR 被创建或更新时自动触发审查,审查结果直接发布为 GitHub PR Review 评论。

Lp1

High
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The code reads multiple environment variables, including GitHub and Anthropic credentials, yet the declared skill surface does not appear to disclose or constrain that capability. In a skill ecosystem, undeclared access to secrets is dangerous because users and orchestrators may grant trust based on the manifest while the code can perform broader authenticated network actions than expected.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · references/anti-patterns.md (reported line 205)May include surrounding context.

md
// ❌ 反模式:直接使用用户输入作为文件路径
app.get("/files/:name", (req, res) => {
  const filePath = path.join("/uploads", req.params.name);
  res.sendFile(filePath); // 用户可以传 ../../etc/passwd
});

// ✅ 正确:验证路径不超出预期目录

Unvalidated Output Injection

High
Category
Output Handling
Confidence
65% confidence
Finding

Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Content

Scanner excerpt · references/anti-patterns.md (reported line 223)May include surrounding context.

4.4 XSS(跨站脚本)

typescript
// ❌ 反模式:直接渲染用户输入
return <div dangerouslySetInnerHTML={{ __html: userComment }} />;

// ✅ 正确:使用框架的自动转义,或使用 DOMPurify
import DOMPurify from "dompurify";

Unvalidated Output Injection

High
Category
Output Handling
Confidence
65% confidence
Finding

Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Content

Scanner excerpt · references/anti-patterns.md (reported line 227)May include surrounding context.

4.4 XSS(跨站脚本)

typescript
// ❌ 反模式:直接渲染用户输入
return <div dangerouslySetInnerHTML={{ __html: userComment }} />;

// ✅ 正确:使用框架的自动转义,或使用 DOMPurify
import DOMPurify from "dompurify";

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README states that the --lang parameter defaults to zh, which imposes a specific language choice unless the user explicitly overrides it. This is reinforced elsewhere by REVIEW_LANGUAGE defaulting to zh, creating a locale policy concern because the skill does not present language selection as opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The environment variable table defines REVIEW_LANGUAGE with a default of zh, meaning automated webhook reviews will be produced in Chinese unless changed. Forcing a locale in automated behavior without opt-in is a natural-language policy violation under the language/locale rule.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The webhook mode describes automatic forwarding of PR-derived content to Anthropic and interactions with GitHub APIs, but does not provide a prominent user-facing notice or consent boundary for external transmission. In practice, this can cause unreviewed source code, comments, or sensitive repository context to be sent to third parties, creating confidentiality and compliance risks.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code sends PR diffs and metadata to Anthropic for analysis, but the skill description does not clearly disclose third-party data transmission. Repository diffs often contain proprietary code, secrets, or sensitive business logic, so undisclosed external sharing creates confidentiality and compliance risks.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The implementation reads external-provider credentials and uses them to transmit repository diffs to an outside service, which is a sensitive capability beyond basic local review logic. Because the purpose sounds like code review rather than data export, this increases the chance that operators underestimate the confidentiality impact of enabling the skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The hardcoded external endpoint confirms that repository content is transmitted off-platform to a specific third-party API. That is especially sensitive here because the skill processes code changes from GitHub PRs, which may contain proprietary logic, embedded secrets, or unpublished fixes.

Content

Scanner excerpt · index.ts (reported line 533)May include surrounding context.

ts
console.log(`[Review] 执行审查片段 ${i + 1}/${prompts.length}...`);

    try {
      const response = await fetch("https://api.anthropic.com/v1/messages", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The hardcoded external endpoint confirms that repository content is transmitted off-platform to a specific third-party API. That is especially sensitive here because the skill processes code changes from GitHub PRs, which may contain proprietary logic, embedded secrets, or unpublished fixes.

Content

Scanner excerpt · index.ts (reported line 533)May include surrounding context.

ts
console.log(`[Review] 执行审查片段 ${i + 1}/${prompts.length}...`);

    try {
      const response = await fetch("https://api.anthropic.com/v1/messages", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

PR diff content and metadata are transmitted to a third-party AI API without an explicit user-facing warning or consent flow. This is dangerous because users may submit private or regulated source code expecting local analysis, leading to unintentional disclosure outside their security boundary.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description presents a PR review tool that accepts a PR URL, local diff, or commit hash, but the implementation exposes a network-facing webhook service that automatically receives GitHub events and posts reviews back to repositories. That capability expansion matters because it changes the trust and attack model: running a server with repo-writing behavior is materially riskier than a local or user-invoked reviewer.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document title and introductory instructions are entirely in Chinese, with no indication that users may choose another language or that the file is intended only for a Chinese-speaking or region-specific audience. This is a natural-language locale constraint that can violate organizational language-choice policies when not explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

该 markdown 文件以中文标题和说明直接规定了 review 评论示例与输出风格,但没有说明这是特定中文团队场景,也没有给出语言选择或用户 opt-in。根据规则,强制特定语言而缺少选择或合理限定,属于自然语言层面的语言/locale policy violation。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The argument description states --lang=zh|en with default zh, and the output section repeats that the default language is Chinese. This imposes a locale/language default rather than offering a neutral choice or requiring opt-in, which can violate language/locale policy when not justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documented default for REVIEW_LANGUAGE is 'zh', and the prompt builder enforces Chinese output unless 'en' is explicitly configured. This creates a language policy concern because the skill forces a specific language by default rather than offering a neutral default or explicit user choice at invocation time.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The prompt builder chooses Chinese whenever no language option is supplied, producing review output in a fixed language by default. This is a natural-language policy issue because users are not given an explicit language choice at the point of use.

Content

No source excerpt is available for this finding.