Back to skill

Security audit

travel-itinerary-builder

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent travel-itinerary generator, but its HTML template has a confirmed script-injection risk and its activation/output rules are broader than necessary.

Review before installing if you plan to generate HTML from untrusted trip details, place names, or shared prompts. The template should avoid inline onerror handlers and preferably use DOM APIs/textContent before the generated files are opened, hosted, or shared. Expect the skill to produce Simplified Chinese HTML travel handbooks, not short travel answers.

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
assets/template.html:523
Finding

DOM-Based Script Injection Through the Image Error Handler

Content
View full analysis
'; ``` The HTML escaping helper used elsewhere in the renderer is: ```javascript function esc(s) { return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } ``` ### Technical Analysis The renderer interpolates `spot.name` into the JavaScript source of an inline `onerror` event handler. Although `encodeURIComponent()` is applied, it is not a JavaScript-string escaping function and does not encode every character that can affect this context. In particular, an apostrophe remains unencoded and can terminate the single-quoted `this.src` value. The `esc()` helper cannot address this issue because it is designed for HTML text and double-quoted attribute contexts, not for untrusted data embedded inside a JavaScript string inside an HTML attribute. This nested parser context requires avoiding source-code interpolation entirely. For example, a crafted attraction name shaped like: ```text '-alert(document.domain)-' ``` can produce an event handler structurally equivalent to: ```javascript this.src='data:image/svg+xml,...'-alert(document.domain)-'%3C/text%3E...'; ``` This is syntactically executable JavaScript. The injected expression is evaluated when the original image fails to load. The current bundle ...[truncated 1783 chars]
Remediation
View remediation
' + '' + '' + escapeXmlText(String(spot.name)) + ''; img.src = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg); }); return img; } function escapeXmlText(value) { return value .replace(/&/g, '&') .replace(//g, '>'); } ``` 2. **Prefer DOM construction over `innerHTML`.** Build dynamic cards with `createElement()`, `textContent`, `setAttribute()`, and `appendChild()`. This prevents data from crossing HTML and JavaScript parser boundaries. 3. **Validate generated itinerary fields.** Treat attraction names, image paths, transport text, and other generated fields as untrusted. Apply field-length limits and reject control characters where they are unnecessary. 4. **Encode by destination context.** Use `textContent` for visible text and direct property assignment for URLs. Do not use URL encoding as a substitute for JavaScript or HTML escaping. 5. **Add a restrictive Content Security Policy after removing inline handlers.** For example: ```html
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger conditions are extremely broad, including generic terms like '旅行', '旅游', '行程', '攻略', 'itinerary', and 'travel plan'. This can cause the skill to activate for ordinary travel-related conversation where the user did not ask for a full itinerary, leading to incorrect tool/skill routing, over-collection of context, and unexpected HTML output instead of a normal answer.

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

md
**始终生成自包含的 HTML 单文件**,零外部 CDN 依赖。使用 `assets/template.html` 作为 CSS 和 JS 架构模板。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**始终生成自包含的 HTML 单文件**,零外部 CDN 依赖。使用 `assets/template.html` 作为 CSS 和 JS 架构模板。

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest description uses catch-all activation language such as '任何涉及' combined with broad travel-related keywords, which makes invocation boundaries ambiguous. In a routing system, this increases the chance of accidental activation and inappropriate response shaping, especially because the skill forces a specific output format and behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill hard-codes Simplified Chinese output without checking the user's language preference or obtaining opt-in. This can override user intent, reduce usability, and in some contexts create trust, accessibility, or policy issues if the assistant responds in an unexpected language or script.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file contains user-facing skill documentation only in Chinese, which can constitute a language/locale policy violation when no opt-in or alternative language is provided. The file does not indicate that the skill is region-specific or that users may choose another language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The page sets lang="zh-CN", and the visible content is written entirely in Simplified Chinese, which imposes a specific language/locale experience. Under the stated policy, locale constraints should either be user-selectable or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.