Back to skill

Security audit

Export Reply

Security checks for vulnerabilities and agentic risk

Overview

The skill is a plausible local conversation exporter, but its PDF/HTML export path has under-disclosed security risks that users should review before installing.

Review this skill carefully before installing. Prefer MD or TXT export for sensitive conversations, avoid HTML/PDF export on untrusted or attacker-supplied content, and clear ~/.export_reply_prefs.json if you do not want export paths remembered. If you use it, choose explicit export requests and inspect the destination path before confirming full-conversation saves.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export_reply.py:110
Finding

Predictable and Insecure Temporary File Handling

Content
View full analysis
Path: import tempfile, subprocess # Strategy 1: Chrome / Chromium headless (best quality, CJK native) chrome = _find_chrome() if chrome: html_tmp = Path(tempfile.mktemp(suffix=".html")) try: write_html(content, html_tmp, title) result = subprocess.run( [ chrome, "--headless", "--disable-gpu", "--no-sandbox", "--run-all-compositor-stages-before-draw", f"--print-to-pdf={output_path}", "--print-to-pdf-no-header", str(html_tmp), ], capture_output=True, timeout=30, ) if output_path.exists() and output_path.stat().st_size > 1000: return output_path except Exception: pass finally: html_tmp.unlink(missing_ok=True) # Strategy 2: weasyprint try: from weasyprint import HTML as WH html_tmp = Path(tempfile.mktemp(suffix=".html")) write_html(content, html_tmp, title) WH(filename=str(html_tmp)).write_pdf(str(output_path)) html_tmp.unlink(missing_ok=True) return output_path except ImportError: p ...[truncated 2199 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/export_reply.py:45
Finding

Untrusted HTML Rendering with Browser Sandbox Disabled

Content
View full analysis
Path: try: import markdown as md_lib body_html = md_lib.markdown(content, extensions=['fenced_code', 'tables', 'toc']) except ImportError: # Fallback: wrap in
text
 if markdown lib unavailable
        import html as html_lib
        body_html = f"
text
{html_lib.escape(content)}
" import html as _html_mod title_esc = _html_mod.escape(title) html = f""" {title_esc} body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 860px; margin: 48px auto; padding: 0 24px; color: #1a1a1a; line-height: 1.7; }} h1, h2, h3 {{ border-bottom: 1px solid #e5e7eb; padding-bottom: 6px; }} code {{ background: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-size: 0.9em; }} pre {{ background: #f3f4f6; padding: 16px; border-radius: 8px; overflow-x: auto; }} pre code {{ background: none; padding: 0; }} blockquote {{ border-left: 4px solid #d1d5db; margin: 0; padding-left: 16px; color: #6b7280; }} table {{ border-collapse: collapse; width: 100%; }} th, td {{ border: 1px solid #e5e7eb; padding: 8px 12px; text-align: left; }} th {{ background: #f9fafb; }} .meta {{ color: #9ca3af; font-size: 0.85em; margin-bottom: 32px; }}

{title}

导出时间 / Exported at:{datetime.now().strftime('%Y-%m-%d %H:%M')}

{body_html} """ output_path.write_text(html, en ...[truncated 3573 chars]
Remediation
View remediation
{title_esc} ``` 4. Remove `--no-sandbox`. If the deployment environment genuinely cannot run the browser sandbox, perform rendering in a separately isolated container with: - No network access - A read-only filesystem - A dedicated unprivileged user - Minimal mounted files - CPU, memory, and execution-time limits 5. Prevent remote-resource loading during rendering. Use a restrictive Content Security Policy such as: ```html ``` 6. Configure WeasyPrint, pdfkit, and other fallback renderers with equivalent controls because they also process generated HTML. 7. Add security tests covering raw `

T08 · Insecure Dependencies

Note
Location
SKILL.md:35
Finding

Unpinned and Unverified Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The core export functionality and supported formats align well with the description: the code writes content to local files in MD, TXT, HTML, PDF, and DOCX. However, several declared user-facing capabilities are absent. There is no logic for producing a condensed summary, no bilingual processing, and no storage of previous export settings for repeat use. The script is a generic command-line exporter taking --content or --file input, not a conversation-aware skill that directly captures an agent reply or full conversation by trigger. These are material gaps between declared behavior and actual implementation, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

There is a material description-to-behavior mismatch. The code does align partially with local export behavior and supports two declared modes in a limited sense ('raw' vs 'summary' templates). However, its actual role is much narrower: it formats already-prepared content and writes a Markdown file. The declared description promises a broader export feature set, including multiple output formats and remembering prior settings, none of which appear in this code. The docstring explicitly says the agent provides pre-summarized content, so the script is not itself responsible for generating the condensed summary.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger phrases include very broad one-word commands like 'save' and 'export', which can easily occur in ordinary conversation. This raises the risk of accidental activation, causing the agent to write conversation content to disk or initiate export workflows without the user meaning to invoke the skill.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Repeating ambiguous one-word triggers in the usage section reinforces unsafe invocation patterns and makes accidental triggering more likely in natural dialogue. In this skill's context, accidental activation is more dangerous because the action writes potentially sensitive conversation content to local storage.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
97% confidence
Finding

The skill contains hidden instructions in an HTML comment that are not rendered to users but direct agent behavior. Hidden operational directives reduce transparency and can conceal security-relevant actions such as preference storage, shell invocation, and file export behavior, preventing users from giving informed consent.

Content

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

text

---
<!-- Agent instructions below. Not rendered on ClawHub. -->

## Interaction Flow (MUST follow exactly)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs the agent to invoke shell commands and perform file reads/writes, but it does not declare an explicit tool scope such as permissions or allowed-tools. That creates a trust and containment gap: a user or platform cannot easily tell that local filesystem access and command execution are required, increasing the chance of unintended data export or misuse.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill explicitly supports exporting full conversations and storing reusable preferences, which can include sensitive transcript content and user-chosen filesystem paths. This increases the privacy impact of misuse or accidental activation because more data is retained locally and future exports become easier to repeat.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The user-facing description highlights convenience features but does not clearly warn that the skill writes conversation content to local files and persists preferences on disk. Without prominent disclosure, users may unknowingly store sensitive transcripts or filesystem paths in places they did not intend.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

Raw mode preserves user and assistant content verbatim, which can include secrets, personal data, credentials, or regulated information. In an export skill this behavior is expected, but it is still security-sensitive because it increases the chance that sensitive material will be stored in plain text without redaction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The instructions require every summary header and prose block to be bilingual with Chinese first, which imposes a language/locale behavior by default. The file does not present this as an opt-in choice or explain a region-specific need, so it conflicts with the policy against forcing a specific language without user consent.

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 HTML sets lang="zh-CN", and elsewhere the script defaults to Chinese titles/messages, which imposes a specific language/locale on exported content. The policy allows locale constraints only when user choice or clear justification is provided, which is not present here.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a local export skill that saves replies/conversations to files in various formats. In addition to file conversion, the code discovers Chrome/Chromium on the host and launches it via subprocess for headless rendering, which is a materially broader execution capability than simple local file export.

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/export_reply.py (reported line 118)May include surrounding context.

python
html_tmp = Path(tempfile.mktemp(suffix=".html"))
        try:
            write_html(content, html_tmp, title)
            result = subprocess.run(
                [
                    chrome,
                    "--headless", "--disable-gpu", "--no-sandbox",

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script writes user-provided content to output paths in multiple formats, including creating directories and saving files, but it does not provide any warning about overwriting existing files or the implications of persisting potentially sensitive conversation content. For safety-relevant file writes, the audit criteria require some visible disclosure unless clearly covered by the skill description, which is not present in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The preference summary returned by describe_prefs is hard-coded in Chinese, which imposes a specific language on users without opt-in. The policy allows locale constraints only when they are user-selectable or clearly justified as region-specific, which is not indicated here.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/prefs.py (reported line 82)May include surrounding context.

python
print("null")

    elif args.action == "set":
        missing = [f for f in ("scope", "mode", "format", "path") if not getattr(args, f)]
        if missing:
            print(f"ERROR: missing --{missing[0]}", file=sys.stderr)
            sys.exit(1)

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The function and CLI both default the exported document title to "对话导出", and the templates prominently include Chinese text alongside English. This imposes a specific locale/language choice by default without any explicit user opt-in or language-selection mechanism, which matches the policy concern for forced language/locale behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.