Back to skill

Security audit

book-capsule-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local book-excerpt HTML generator, but it needs review because untrusted content can become executable browser code in the generated article.

Install only if you are comfortable with a skill that writes local files and runs its bundled Python generator automatically. Use trusted JSON/content sources, review generated HTML before opening or publishing it, and avoid feeding it web-scraped or user-supplied text unless the generator is updated to escape or sanitize HTML.

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

Error
Location
generate-book-article.py:121
Finding

Unescaped JSON Content Permits Stored HTML and JavaScript Injection

Content
View full analysis
str: """为一条金句生成独立 HTML 块。""" text = gq.get('text', '') source = gq.get('source', '') if source: return GOLD_QUOTE_BLOCK_TEMPLATE.replace('{TEXT}', text).replace('{SOURCE}', source) else: return GOLD_QUOTE_BLOCK_NO_SOURCE_TEMPLATE.replace('{TEXT}', text) ``` ```python title = data.get('title', '') if data.get('title_line2'): line2 = data['title_line2'] line2 = (line2 .replace('{count}', str(total_cards)) .replace('{all_quotes}', str(total_all_quotes)) .replace('{quotes}', str(total_quotes))) title += '
' + line2 html = html.replace('{{TITLE}}', title) html = html.replace('{{SUBTITLE}}', data.get('subtitle', '')) intro = data.get('intro_paragraphs', []) html = html.replace('{{INTRO_PARAGRAPH_1}}', intro[0] if len(intro) > 0 else '') html = html.replace('{{INTRO_PARAGRAPH_2}}', intro[1] if len(intro) > 1 else '') ``` ```python html = f'\n\n\n\n\n{data.get("title", "")}\n\n\n{html}\n\n' ``` ### Technical Analysis The generator treats JSON values as trusted HTML and inserts them directly into HTML templates through string replacement and f-string interpolation. It does not apply HTML escaping, contextual output encoding, or markup sanitization. The affected data includes card numbers, titles, descriptions, quote text, quote sources, article tit ...[truncated 2766 chars]
Remediation
View remediation
str: return escape(str(value), quote=True) ``` 2. Escape values before inserting them into text, attribute, or `` contexts: ```python safe_text = escape_text(q.get('text', '')) safe_index = escape_text(q.get('index', f'{j + 1:02d}')) quote_parts.append( QUOTE_ITEM_TEMPLATE .replace('{INDEX}', safe_index) .replace('{TEXT}', safe_text) ) ``` 3. Do not preserve arbitrary HTML merely to support line breaks. Instead, escape the entire value and then convert only an explicitly supported representation: ```python def escape_with_breaks(value) -> str: safe = escape(str(value), quote=True) return safe.replace('\r\n', '\n').replace('\r', '\n').replace('\n', '<br>') ``` If backward compatibility with literal `<br>` is required, normalize and allow only exact `<br>`, `<br/>`, or `<br />` tokens after escaping. Do not use a broad tag-removal regular expression as a sanitizer. 4. Use a template engine with automatic escaping enabled rather than constructing HTML through unrestricted `str.replace()` operations. Treat any deliberately safe HTML fragment as a separate, explicitly typed value. 5. Add strict schema validation: - Require expected types for all fields. - Reject objects or arrays where strings are expected. - Validate `after_card` as a bounded non-negative integer. - Impose reasonable length and collection-size limits. - Reject unsupported fields or markup where practical. 6. Add regression tests covering payloads in every interpolated field, including: ```html link ``` Tests should confirm that these values appear only as inert text in the generated document while supported line breaks continue to render correctly. 7. Consider applying a res ...[truncated 157 chars]
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description is entirely written in Chinese and presents the workflow and usage as Chinese-only, with no indication that users may choose another language or that the skill is intentionally restricted to a Chinese-language audience for a documented reason. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs the agent to write a JSON file locally and invoke a shell command, but it does not declare any explicit tool scope or permission boundaries. This creates an over-privileged execution pattern where file system and command execution capabilities may be available without clear limitation or user awareness, increasing the chance of unintended local writes or misuse if the workflow is adapted or the inputs become unsafe.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill description and instructions are entirely in Chinese and define Chinese-language output conventions, but there is no indication that the user can choose another language or that the locale restriction is required for a justified regional purpose. This can violate language/locale policy when a skill implicitly forces a specific language without opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrases are broad natural-language requests like '做书摘' and '浓缩一本书', which can match ordinary user intent and cause the skill to activate unexpectedly. Unintended activation is risky here because the skill performs side effects, including local file creation and shell-based HTML generation, without an explicit confirmation step.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill description and workflow do not warn the user that local files will be written and a shell command will be executed. This reduces informed consent and can lead users to trigger filesystem and process side effects unknowingly, which is especially problematic in environments where shell execution is sensitive.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This JSON content presents all user-facing titles, descriptions, and quotes exclusively in Chinese, but does not indicate that the skill is intended only for Chinese-speaking users or that language selection is optional. Under the policy, forcing a specific language without user opt-in can be a natural-language locale violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Several trigger phrases such as '做书摘' or '浓缩一本书' are generic enough to match normal reading, summarization, or note-taking requests that may not explicitly intend to invoke this skill. This can cause unintended activation, leading the agent to access local files or publish content when the user only asked for general help, which is a real safety and consent issue even without malicious intent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language instructions and labels in the file force a specific language/locale experience for anyone using the template. The policy allows this only when the skill offers user choice or clearly documents a justified region-specific constraint, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The generated document hard-codes lang="zh-CN", which imposes a specific language/locale on all output. The file does not offer a user option to select another locale or explain that the tool is intentionally limited to a China-specific publishing context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This HTML template presents all instructions and end-user visible content exclusively in Chinese, and there is no indication that the user can select another language or that the locale restriction is intentional. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Natural-language text in the manifest presents the skill solely in one language without stating that it is China-specific or offering multilingual use. That can create a language policy concern if the broader environment expects neutral language support or user opt-in for locale-specific behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file presents all user-facing instructions in Chinese starting from the title, with no indication that users may choose another language or that the locale restriction is intentional. That can violate a language/locale policy when a skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.