Back to skill

Security audit

见好·旅行规划器 (jianhao-travel-planner)

Security checks for vulnerabilities and agentic risk

Overview

This is a Chinese travel-planning skill that creates itinerary files and optional shareable web assets, with its network and local file use disclosed and aligned with that purpose.

Install this if you want a Chinese-language travel-planning workflow that performs online research and writes itinerary artifacts. Prefer project-level installation if you do not want broad global activation. Before running tools/desource.py, review rules.json carefully because it can overwrite the configured friend-version file after creating a backup. If you use Pexels, treat the API key and search terms as data sent to that third party, and review generated public versions for private details before sharing.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (20)

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The activation description says the skill will be automatically triggered when the user says phrases like "周末想去 XX 玩", and earlier describes usage as saying "想出去玩". These are common everyday expressions rather than narrowly scoped commands, and the README does not provide exclusion conditions or clearer trigger boundaries, increasing the risk of unintended invocation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented workflow claims destination selection, online verification, and itinerary generation, but substantial behavior revolves around batch local file mutation, version derivation, redaction, and HTML content insertion/removal. In context, this is more dangerous because the deceptive framing hides nontrivial file-manipulation capabilities inside a broadly triggered consumer skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented workflow claims destination selection, online verification, and itinerary generation, but substantial behavior revolves around batch local file mutation, version derivation, redaction, and HTML content insertion/removal. In context, this is more dangerous because the deceptive framing hides nontrivial file-manipulation capabilities inside a broadly triggered consumer skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The entire skill description and all example interactions are presented only in Chinese, with no indication that users may choose another language or that the skill is intentionally restricted to a Chinese-only audience for compliance reasons. This can constitute a language-policy issue when the skill implicitly enforces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file says "你说'想出去玩',它按固定流程..." which presents activation as a broad natural-language condition. Because the README does not limit activation to a command palette, explicit skill name, or other narrow context, it is unclear when the skill should activate versus when a user is merely chatting about travel.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 39)May include surrounding context.

md
- **全局**(推荐):`~/.claude/skills/`(Windows 即 `C:\Users\<用户名>\.claude\skills\`)
- **单项目**:`<项目>\.claude\skills\`

装好后的路径应该是 `…/skills/jianhao-travel-planner/SKILL.md`。放对之后,跟 AI 说"周末想去 XX 玩"就会被自动触发。

目录结构(缺一不可):

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill explicitly instructs installation into a local skills directory and references bundled tools that read, rewrite, and back up local files, but it declares no permissions or allowed-tools scope. That creates an overbroad capability surface where a user or host system cannot easily constrain file operations to the minimum necessary, increasing the risk of unintended local file access or modification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are extremely broad and overlap with ordinary travel conversation, making accidental activation likely. In this skill, that matters because activation can lead into local file-generation and modification workflows, so users may invoke more capability than intended from a casual request.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

At L066, the skill explicitly says language translation aids are withdrawn and that it 'does not do a language module.' Later, the described post-trip pipeline includes '多语言适配' as an output, which contradicts the earlier documented scope and creates an intent mismatch about whether language adaptation is part of the skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file states the target users are domestic travelers and explicitly omits language features because they are considered unnecessary for that audience. Elsewhere the document consistently assumes Chinese platforms, Chinese terminology, and Chinese-language outputs, but it does not offer an opt-in choice for other languages or locales.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The skill directs use of an external API and passing an Authorization key to retrieve images, which constitutes outbound network transmission to a third party. In context this is moderately sensitive because the skill also encourages embedding externally sourced content into generated artifacts, and users may not realize their queries, destination terms, or API credentials are being sent off-platform.

Content

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

md
- **每一天都要有图**:`<figure>` 放在 `.day` 里、`.day-head` 之后,外层 `<div class="photos">`(双列)或 `<div class="photos single">`(单列)——**骨架 CSS 本来就带 `.photos` 全套规则**。
   - 图必须 **base64 内嵌**(单文件断网可开);**逐张眼见亲选剔错图**,别信文件名;**非本趟实拍的一律标「(示意)」**,并在页脚写明「哪些是实景 / 哪些是同题材示意 + 图源」。
   - 🔴 **图源的现实(2026-09-15 实测)**:`commons.wikimedia.org`、`upload.wikimedia.org`、`zh.wikipedia.org`、`api.wikimedia.org` 在**境内直连网络全部不可达**——**不是偶发、别再等它通**。**有代理/海外网络环境时 Wikimedia Commons 可用**——真实地标实拍质量高(挑图纪律见 v3.30:核对拍摄对象+年份,古画/在建照/重滤镜跳过)。
     → **首选 Pexels**(免费可商用):key 获取见「工具与依赖」(2 分钟免费注册),直接打 API `https://api.pexels.com/v1/search?query=<词>&per_page=4&orientation=landscape`(带 `Authorization: <key>`)。
   - **选图纪律**:地标类优先挑**真在当地的**;本地小众景点 Pexels 没有 → **同题材素材 + 标「(示意)」**,**绝不用别处照片冒充当地实景**。
   - 🔴 **验收要出数字,不能靠肉眼**:`document.querySelectorAll('.photos img')` 逐张查 `naturalWidth>0 && rect.width>50` 才算真渲染;再跑四档视口(320/390/768/1280)确认无横向溢出(base64 大图最容易在窄屏撑破)。
   - 🔴 **反例**:某版首版 **0 张图(96KB)**,而成熟版 8 张(1.23MB)——`.photos` 的 CSS **一直在**,只是生成脚本从没产出 `<figure>`,于是「骨架在、内容缺」,看 CSS 或跑原四检都发现不了。→ **交付前直接数 `<figure>` 个数 ≥ 行程天数**(进自查清单⑱)。

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest frames the skill as a travel-planning and itinerary-generation workflow, including verification and trip adjustments. However, this section adds capabilities for public deployment, channel-specific distribution tactics, DM delivery, watermarking, and release-material packaging for Douyin/WeChat, which are marketing/publishing functions rather than core travel planning.

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 collecting requirements, planning destinations, verifying trip details, generating itineraries, adjusting during travel, collecting materials, and review feedback. But these lines go further into producing Xiaohongshu copy, covers, Douyin hooks, and WeChat article adaptation, which are editorial/social-content capabilities distinct from planning travel itineraries.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes a travel-planning skill that gathers requirements, screens destinations, verifies key information online, produces itineraries, and dynamically adjusts travel plans. This file instead batch-processes local files to generate a private/internal HTML version and sanitize a public/friend version, which is a content-production/post-processing utility rather than an obvious end-user travel-planning capability.

Content

No source excerpt is available for this finding.

Tainted flow: 'self_s' from pathlib.Path.read_text (line 248, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · tools/desource.py (reported line 255)May include surrounding context.

python
'自用版·情报原档章节')
    assert '\\n' not in self_s and '\\1' not in self_s, '自用版出现字面转义残留'
    out_self = Path(rule['self'])
    out_self.write_text(self_s, encoding='utf-8')
    log(f"  → 写出 {out_self.name}({len(self_s)} 字符,+{len(self_s)-base})")

    # ---- (2) 朋友版(剥离)

Tainted flow: 's' from pathlib.Path.read_text (line 269, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · tools/desource.py (reported line 283)May include surrounding context.

python
bak = f.with_name(f.name + f'.bak-{stamp}')
    shutil.copy2(f, bak)
    log(f"  → 备份 {bak.name}")
    f.write_text(s, encoding='utf-8')
    log(f"  → 写出 {f.name}({len(s)} 字符,-{base-len(s)})")
    return dict(city=rule['city'], base=base, self_bytes=len(self_s), friend_bytes=len(s),
                removed=base - len(s))

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document root sets lang="zh-CN", which hard-codes a specific language/locale for the skill output. The file does not offer any user opt-in, alternate locale handling, or justification that this template is intended only for a China-specific audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

Line L002 sets the page language to "zh-CN", and the visible UI text throughout the file is exclusively Chinese. Under the policy rule, forcing a specific language without user opt-in is a natural-language locale policy violation unless the restriction is clearly justified, which this template does not provide.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains natural-language instructions, status messages, and usage documentation entirely in Chinese, indicating the skill is designed to operate in a single language without any visible opt-in or locale selection. Under the stated policy, forcing a specific language without user choice 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
91% confidence
Finding

The module docstring, CLI description, and user-facing log strings are entirely in Chinese, which imposes a specific language/locale on users. Under the policy, locale-specific behavior should either offer opt-in/choice or clearly document why the constraint is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.