Back to skill

Security audit

Repo Onboarding Guide

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a local repository onboarding reporter, but it needs review because its scanner can follow symlinks and may read files outside the repository the user intended to scan.

Install only if you are comfortable giving it read access to the repository tree being scanned. Avoid running it on untrusted repositories until symlink containment and file-size limits are added, and prefer dry-run/stdout output unless you explicitly want it to create a report file.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/run.py:33
Finding

Repository Symlink Traversal Allows Out-of-Scope Local File Reads

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py, lines 33–40 and 66–75
Vulnerability Type: Symlink traversal and insufficient repository-boundary validation
Risk Level: Medium

Vulnerable Code

python
def list_text_files(root: Path, limit: int = 50):
    results = []
    for path in root.rglob("*"):
        if len(results) >= limit:
            break
        if path.is_file():
            if path.suffix.lower() in {".md",".txt",".json",".yaml",".yml",".py",".js",".ts",".csv",".tsv",".sh"}:
                results.append(path)
    return results
python
def directory_report(spec: dict, root: Path, limit: int) -> str:
    files = list_text_files(root, limit=limit)
    ext_counter = Counter(p.suffix.lower() or "<none>" for p in files)
    headings = []
    for p in files[: min(10, len(files))]:
        if p.suffix.lower() == ".md":
            text = read_text(p)
            for line in text.splitlines():
                if line.startswith("#"):
                    headings.append((p.name, line.strip()))

Technical Analysis

The directory scanner recursively enumerates paths under a user-supplied repository with Path.rglob(). It then calls Path.is_file(), which follows symbolic links, and accepts each candidate based only on its apparent filename extension.

Before read_text() opens an accepted Markdown path, the implementation does not:

  • reject symbolic links;
  • resolve the candidate to its canonical target;
  • verify that the resolved target remains under the resolved repository root; or
  • enforce a maximum file size before reading the entire file into memory.

Consequently, a repository-controlled symbolic link with a supported extension can point to an arbitrary file that is readable by the process. When such a link has a .md suffix and is among the first ten sampled files, the target is opened and read in full. Lines beginning with # are subsequently included in the generated report.

This violates t ...[truncated 1932 chars]

Remediation
View remediation

Remediation Suggestions

  1. Reject symbolic links before classifying or reading candidate files:
python
if path.is_symlink():
    continue
  1. Resolve both the repository root and every candidate, then enforce canonical containment:
python
root_resolved = root.resolve()

for path in root.rglob("*"):
    if path.is_symlink():
        continue

    try:
        candidate = path.resolve(strict=True)
        candidate.relative_to(root_resolved)
    except (FileNotFoundError, RuntimeError, ValueError):
        continue

    if not candidate.is_file():
        continue
  1. Open and read the validated canonical path rather than reusing an unchecked path. Where practical, use descriptor-based checks or compare file metadata before and after opening to reduce time-of-check/time-of-use risks.

  2. Enforce a conservative maximum file size before reading:

python
MAX_TEXT_FILE_SIZE = 1_000_000

if candidate.stat().st_size > MAX_TEXT_FILE_SIZE:
    continue
  1. Read only the bounded prefix or number of lines needed for heading extraction instead of calling read_text() on the entire file.

  2. Apply the same containment, symlink, and size validation to every mode that accepts files or recursively enumerates directories, including pattern scanning.

  3. Add automated tests covering:

    • a supported-extension symlink to a file outside the repository;
    • a symlink chain that resolves outside the repository;
    • a broken symlink;
    • an oversized linked or regular file;
    • a valid regular file inside the repository;
    • confirmation that no out-of-root content appears in generated reports.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

该代码确实包含一部分与声明相符的能力:可扫描目录中的文本文件、README/Markdown 标题并生成结构化报告。但其实际设计明显是一个通用本地审计/报告脚本,而不是专门用于“新成员上手路径、推荐阅读顺序与踩坑提醒”的单一 onboarding 工具。核心分歧在于:1) 代码通过 spec['mode'] 分派到 directory_audit、csv_audit、pattern_audit、skill_audit、structured_brief 等多种模式;2) pattern_report 会执行安全模式匹配,检测 secrets、高危 shell 模式和私有 URL;3) skill_audit 会检查 Skill 项目文件完整性与 SKILL.md frontmatter;4) csv_report 会对表格数据做字段统计。这些都是实质性的未声明能力,且使主要用途扩展为通用审计/规范检查。虽然代码没有发现外传数据或执行构建命令,但描述未准确覆盖其更广泛、且偏安全审计/规范检查的实际行为,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

该 README 是 markdown 文件,适用 SQP-1。L34-L35 的触发示例如“扫描这个仓库生成 onboarding guide”“帮新人找到先看哪些目录”属于自然语言宽泛表述,缺少明确的触发边界、限定条件或负例说明,容易与普通协作对话重叠而被意外路由到该技能。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file is entirely written in Chinese, but it does not state that the skill is China-specific, Chinese-only, or that users may choose another language. Per the policy, forcing a specific language without opt-in or documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises only a documentation/onboarding function, but it declares runtime requirements and instructions that enable shell execution and output-file creation without any explicit tool-scope restriction such as allowed-tools or permissions. In an agent framework, this creates unnecessary capability exposure and weakens least-privilege controls, increasing the chance that the skill is invoked with broader powers than its stated purpose requires.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The description promises a repository scanning and guide-generation workflow, but the instructions also allow running a local program and writing an output file. This hidden expansion from analysis to execution violates principle of least astonishment and can mislead users into granting trust to a skill that has greater operational capability than its top-level description suggests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description and core role definition are written entirely in Chinese and present the skill as operating in that language by default, with no indication that users may choose another language. This is a natural-language locale policy concern because the file does not provide opt-in, alternatives, or a documented region-specific justification.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Providing shell execution to a repository onboarding guide is disproportionate to its stated function of summarizing repository structure and documentation. Even if the example command appears local and benign, shell capability materially increases attack surface because any prompt injection, path manipulation, or future script change could turn a read-oriented skill into one that executes arbitrary local logic.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill's safety section says it is 'default read-only' and only reads directories and filenames, yet the work rules explicitly permit executing a local Python script with input and output files. That contradiction is dangerous because users and orchestration layers may trust the read-only claim while the skill can actually perform side-effecting operations through script execution and file writes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The entire skill file is written in Chinese and presents the skill behavior and output requirements only in that language, with no indication that users may choose another language or locale. Under the stated policy, a language constraint without user opt-in or documented regional justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire example output is written in Chinese and the title indicates this is the expected output format, but there is no indication that the user can choose another language. This creates a natural-language policy concern because it appears to impose a specific language without documented opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The title, category label, summary, examples, and risk description are all written in Chinese, indicating the skill is intended to operate in a fixed language/locale. The file does not offer a user language choice or document that this is a region-specific skill, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The generated report strings are written in Chinese, such as '结果', '摘要', and other section text, with no option for the user to choose language or locale. This creates a natural-language policy issue because the skill enforces a specific language rather than offering an opt-in or documented locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The directory report mode emits fixed Chinese text such as '扫描报告', '目录概览', and '标题样本' with no configurable locale. Because this behavior is embedded in user-facing output and not justified as region-specific, it violates the language/locale policy criterion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Multiple reporting functions generate hard-coded Chinese headings and guidance, including data reports, pattern scan output, and skill audit output. The file provides no language selection mechanism or opt-in, so it forces a specific locale across these user-visible outputs.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The built-in regex patterns detect dangerous shell usage, secret-like strings, and private/internal URLs, producing a security-oriented scan report. That capability is not a direct or obvious requirement for generating onboarding paths and recommended reading order for new contributors.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes a repository onboarding guide that scans repository structure and docs to generate newcomer reading order and pitfalls. However, the code also supports csv_audit, pattern_audit, and skill_audit, including regex-based detection of risky shell commands, secrets, and skill packaging validation, which are semantically broader audit capabilities rather than onboarding-focused guidance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file presents all instructions and test criteria exclusively in Chinese, which can amount to a language/locale policy violation when no user opt-in or justification is provided. The policy allows fixed-language behavior only when the skill offers a choice or clearly documents a justified regional constraint, neither of which appears here.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The code can ingest arbitrary CSV/TSV files and generate field-level summaries and judgments. Auditing tabular datasets is not clearly justified by a skill whose stated purpose is scanning repository directories and documentation to help new members onboard.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.