Back to skill

Security audit

GitHub Repo Guide PDF

Security checks for vulnerabilities and agentic risk

Overview

The skill’s GitHub guide workflow is mostly coherent, but its PDF builder processes generated Markdown with raw TeX enabled, which creates review-worthy local file and resource risks.

Review before installing if you will process untrusted repositories. The skill’s clone-and-guide behavior is expected, but PDF generation should ideally run in a restricted workspace with no sensitive files or credentials accessible, and raw TeX should be disabled or sanitized unless you trust the input.

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

Warning
Location
scripts/build_pdf.py:83
Finding

Untrusted Markdown and Metadata Are Processed with Raw TeX Enabled

Content
View full analysis
str: generated_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S") lines = [ f"# {title}", "", f"- Source: {source_url}" if source_url else "- Source: (not provided)", f"- Generated: {generated_at}", "- Note: this guide focuses on usage, not implementation internals.", "", "\\newpage", "", ] return "\n".join(lines) def ensure_single_document(markdown_path: Path, title: str, source_url: str) -> Path: content = markdown_path.read_text(encoding="utf-8").strip() if not content.startswith("# "): content = f"# {title}\n\n{content}" if content else f"# {title}" first_lines = content.splitlines()[:8] source_line = f"Source: {source_url}" if source_url else None if source_line and source_line not in first_lines: content = content.replace(content.splitlines()[0], content.splitlines()[0] + f"\n\n{source_line}", 1) build_dir = markdown_path.parent / ".build-pdf" build_dir.mkdir(parents=True, exist_ok=True) combined = build_dir / f"{markdown_path.stem}.combined.md" combined.write_text(build_cover(title, source_url) + "\n\n" + content + "\n", encoding="utf-8") return combined ``` ```python for font in fonts: command = [ pandoc, str(combined_md), "--from", "markdown+raw_tex+pipe_tables+task_lists", "--pdf-engine", engine_path, "--toc", "--toc-depth", str(toc_depth), "--number-sections", "-V", f"mainfont={font}", "-V", "fontsize=11pt", "-V", "geometry:margin=1in", "-V", "papersize:a4", "-V", "colorlinks=true", ...[truncated 3078 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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 (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose describes an end-to-end repository documentation skill: ingest a GitHub repo reference, analyze the project, write a Chinese usage guide, produce Markdown and PDF outputs, and return them. The actual code chunk is a narrower helper utility for PDF generation only. Its behavior is limited to validating file paths, combining a cover page with an existing Markdown document, selecting pandoc/PDF engines/fonts, and invoking subprocesses to render a PDF. Those are supporting functions for one part of the declared workflow, but the chunk lacks the primary declared capabilities of repository analysis and guide generation. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes powerful capabilities (gh repo clone, file discovery, file writes, and a Python script) but does not declare any explicit tool scope or permission boundary. That creates ambiguity about what the agent may execute and weakens least-privilege controls, increasing the chance of unintended shell or filesystem actions when the skill is triggered.

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 enough to match common requests about GitHub repositories, tutorials, guides, or PDFs, which can cause the skill to activate in contexts the user did not clearly intend. Because the skill performs cloning, file writes, and command execution, overbroad activation increases the risk of unnecessary external access and side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The description requires the skill to 'produce a Chinese user guide' regardless of user preference. This is a language-policy constraint expressed in natural language, and the file does not indicate that the user can choose another language or opt into Chinese output.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The instructions direct the agent to clone a repository, write files, and execute a Python command, but they provide no user-visible warning or confirmation about these side effects. This can lead to silent command execution and local workspace modification, which is especially risky when processing untrusted repositories or ambiguous prompts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The pandoc invocation hard-codes lang=zh-CN, which imposes a specific language/locale on every generated PDF. This is a natural-language policy concern because the user is not given a choice of locale and the constraint is not justified in the file beyond the high-level docstring.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/build_pdf.py (reported line 159)May include surrounding context.

python
"-o",
            str(output_pdf),
        ]
        result = subprocess.run(command, capture_output=True, text=True)
        if result.returncode == 0 and output_pdf.exists() and output_pdf.stat().st_size > 0:
            return engine_name, font
        errors.append(

Static analysis

No suspicious patterns detected.