T09 · Insecure Skill Coding Practices
- Location
references/templates/todo-sync.js:29- Finding
Cloud synchronization credentials are embedded in client-side JavaScript
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent travel-planning helper, but several optional sync and setup templates could expose private trip data or user credentials if followed as written.
Install only if you are comfortable treating it as a travel-planning template that needs security edits before cloud sharing. Prefer the default localStorage mode, do not put GitHub PATs or JSONBin master keys into static browser code, use private authenticated sync with high-entropy room IDs, review any Docker or compose files before running them, and remove confirmation numbers or personal travel details before publishing or sharing generated pages.
references/templates/todo-sync.js:29Cloud synchronization credentials are embedded in client-side JavaScript
references/cloudflare-workers-sync.md:47Cloudflare Workers synchronization service permits unauthenticated room reads and writes
references/self-host-sync.md:19Self-hosted synchronization service exposes unauthenticated data through the reverse proxy
SKILL.md:57Mutable external MCP deployment artifacts are downloaded and executed without integrity verification
references/templates/index-skeleton.html:152Untrusted marker content is concatenated into Leaflet popup HTML
references/templates/index-skeleton.html:141Third-party Leaflet script is loaded without Subresource Integrity protection
声明描述的是完整旅行攻略生成与规划系统,而该代码片段仅覆盖其中很小的一部分:交互式 Todo 清单的前端状态管理与可选云同步。它不包含旅行信息采集、搜索整合、路线规划、行程文档生成或部署工作流等核心功能,因此主目的与实际行为存在明显差异。此外,代码确实会访问外部服务接口(GitHub、JSONBin、Cloudflare Workers)进行数据同步,而声明中虽提到“可选云端同步”,但未具体披露这些第三方资源;这属于次要但真实的未明示外部访问能力。综合来看,应判定为描述与行为不匹配。
The skill explicitly instructs use of a GitHub Personal Access Token and other cloud service keys for sync. Even though no literal secret is embedded, normalizing credential insertion into client-side or shared trip-planning workflows raises risk of token leakage through browser code, public repositories, shared pages, or accidental exposure to other participants.
### 方案 B:GitHub Gist(零服务器,需 GitHub 账号)
- 把勾选状态 POST 到一个 public Gist
- 用 Personal Access Token(只需 `gist` 权限)
- 代码模板见 `references/templates/todo-sync.js` 的 Gist 变体
### 方案 C:JSONBin.io / jsonbin.io(零服务器,免费 1 万次/月)
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
重载 nginx:
sudo nginx -t && sudo systemctl reload nginx
The code template explicitly uses a GitHub Personal Access Token in front-end JavaScript. Any real token placed here becomes immediately accessible to all site visitors, enabling unauthorized API calls as the token owner, including reading or modifying private gists used for sync and potentially exhausting rate limits or causing account misuse.
// GitHub Gist 配置(仅 SYNC_BACKEND='gist' 时)
const GIST_CONFIG = {
token: 'ghp_xxx', // Personal Access Token(scope: gist)
gistId: '', // 首次留空,自动创建;后续填写 Gist ID
filename: SYNC_ROOM + '.json',
};
The README promotes third-party research sources, maps, web search, and optional cloud sync, but does not clearly warn users what travel data may be transmitted externally. Because itinerary planning often includes sensitive personal details such as dates, budgets, locations, and accommodations, silent or poorly disclosed transmission increases privacy and data-handling risk.
The trigger list is very broad and overlaps with common travel-planning language, which can cause the skill to activate in ordinary conversations without clear user intent. In a skill that performs multi-source research, optional cloud sync, and deployment-oriented workflows, unintended activation can expose user data to external services or cause unnecessary tool use.
The README instructs users to pull a Docker image by mutable name only, without a pinned tag or digest. This creates a supply-chain risk because a later-published or compromised image could be fetched instead of the one the author originally intended, leading users to run unreviewed code on their systems.
The skill instructs use of multiple network-capable components (MCP server, web search, map APIs, cloud sync, deployment) but does not declare any tool scope or allowed-tools boundary. This creates an authorization and transparency gap: a host agent may invoke broader network actions than users or reviewers expect, increasing risk of unintended outbound requests or data disclosure.
The description lists many generic trigger phrases such as “自由行”, “做攻略”, “旅游计划”, “travel plan”, and “itinerary”, which are broad terms a user might say in ordinary conversation rather than explicit skill invocations. The file does not provide narrowing constraints, negative examples, or a specific activation context, increasing the chance of unintended invocation.
Pulling xpzouying/xiaohongshu-mcp without a tag or digest fetches a mutable latest image, exposing users to image replacement or upstream compromise. Because this image is used to run an MCP server with network-facing behavior, a malicious update could execute arbitrary code or exfiltrate accessed data.
The MCP configuration is described as supporting content retrieval and publication to Xiaohongshu, but publication is not necessary for trip planning. Including an unnecessary publish-capable integration expands the action surface and could enable accidental or unauthorized posting if connected tools expose write operations.
The cloud sync guidance encourages use of public Gists, JSONBin, Workers, and custom backends for storing trip checklist state, but does not provide strong privacy warnings or data-minimization guidance. Trip data can reveal travel dates, locations, companions, and other sensitive logistics, and public or weakly protected storage increases exposure risk.
Using npx serve without pinning a version causes execution of whatever package version is current at runtime, which can introduce supply-chain risk or breaking behavior. If the package is compromised or a malicious version is published, users may run attacker-controlled code locally.
The example Worker exposes a world-readable GET endpoint and accepts unauthenticated POST writes for any guessed room ID, while the documentation presents it as a recommended sync service without a prominent warning. In this trip-planning context, stored room data can include itinerary details and collaborative task state, so attackers can overwrite or read travel-related data if IDs are discovered or guessed.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# 写
curl -X POST https://trip-sync.your-subdomain.workers.dev/room/test123 \
-H "Content-Type: application/json" \
-d '{"state":{"u0":true},"ts":1714000000000}'
The service allows any client who knows or guesses a room ID to read and overwrite stored trip data because GET and POST are unauthenticated and CORS permits any origin. In the trip-planning context this is more dangerous because itineraries can contain personal travel dates, destinations, and lodging details, enabling privacy loss and tampering.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
```bash
sudo systemctl enable --now trip-sync
sudo systemctl status trip-sync
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
```bash
sudo systemctl enable --now trip-sync
sudo systemctl status trip-sync
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
```bash
sudo systemctl enable --now trip-sync
sudo systemctl status trip-sync
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
```bash
sudo systemctl enable --now trip-sync
sudo systemctl status trip-sync
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# 读空房间(应返回 {state:null,ts:0})
curl https://your-domain.com/trip-sync/room/test123
# 写
curl -X POST https://your-domain.com/trip-sync/room/test123 \
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
# crontab -e
0 3 * * * tar czf /backup/trip-sync-$(date +\%Y\%m\%d).tar.gz /home/user/trip-sync/data
The HTML document hard-codes lang="zh-CN", and the visible interface text throughout the template is also in Chinese. This creates a natural-language locale constraint without any opt-in, fallback, or documentation that the template is intended only for a China-specific audience.
The template explicitly instructs users to place GitHub PATs and JSONBin master keys directly into client-side JavaScript. In a browser-delivered static page, those secrets are exposed to every visitor via page source or developer tools, allowing anyone to steal the credentials and read, modify, or delete synced data and potentially abuse the linked third-party account.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
const GistBackend = {
async load() {
if (!GIST_CONFIG.gistId) return null;
const r = await fetch('https://api.github.com/gists/' + GIST_CONFIG.gistId, {
headers: { 'Authorization': 'token ' + GIST_CONFIG.token }
});
if (!r.ok) return null;
No suspicious patterns detected.