Back to skill

Security audit

私人旅游管家

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent personal travel database assistant with disclosed local storage, optional web enrichment, and Notion sync.

Install only if you are comfortable with a travel assistant saving local Markdown records and, when you request enrichment or sync, sending place queries or selected records to search/map providers and Notion. Keep API tokens out of chat, review dry-run sync plans before using --apply, and avoid storing sensitive reservation details or private itinerary data unless you want them in the local database or Notion mirror.

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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill instructs access to local .env files, file reads/writes, shell commands, and networked synchronization, but no explicit permission declaration is present. That creates a hidden capability gap where a broadly triggered skill could operate on sensitive local data or external services without clear user/admin consent boundaries.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The skill presents itself primarily as a local travel database manager, but its instructions authorize broader external lookups and multi-source web verification beyond the stated Notion sync use case. This mismatch can cause users or policy layers to underestimate outbound network activity, increasing the risk of unintended data disclosure and over-privileged execution.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The skill metadata describes managing a personal travel database, but this file performs live general web searches across external search engines. That expands the skill's effective capability beyond its declared role, increasing the chance of unexpected data egress and user misunderstanding about where their travel-related inputs are being sent.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
Invoking external CLI tools like ddgs and curl introduces undeclared execution and network-fetch capability into a skill that is presented as a personal travel database manager. This broadens the attack surface, creates dependency trust issues, and can leak sensitive queries or environment context through tools outside the application's direct control.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The code initiates external web searches as part of its normal workflow, despite the skill being described primarily as a manager for a local personal travel database. This expands the skill's data flow beyond local content, potentially sending user-provided travel queries to third-party services without clear necessity, user consent, or manifest-level justification.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The DuckDuckGo integration provides active internet search capability in a skill whose core purpose is organizing a personal travel knowledge base. Even if not overtly malicious, this can expose sensitive or private user itinerary, preference, or location data to external services and makes the skill behavior broader than users may reasonably expect from a local database tool.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The activation criteria are very broad and could match ordinary travel-related conversation, causing the skill to trigger when the user did not intend database modification, file access, or external sync behavior. In a skill with write, shell, env, and network capabilities, overbroad activation materially raises the chance of unintended sensitive actions.

Vague Triggers

Medium
Confidence
85% confidence
Finding
The default prompt activates the skill for a very broad set of user intents ('ingest a travel tip, update the Markdown database, and recommend next steps') without clear boundaries, confirmation steps, or limits on when writes should occur. In a skill that stores and organizes user-provided content, this can cause over-triggering, unintended data ingestion, and accidental persistence of sensitive travel information or screenshots.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The workflow directs the agent to store images, OCR text, use network/search tools, and perform Notion synchronization, but it provides no requirement to obtain user consent, disclose external transmission, or minimize sensitive data before upload. In a personal travel database context, screenshots and travel notes can contain private itinerary details, addresses, names, reservation data, or other personal information, so silent collection and syncing creates a real privacy and data-exposure risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The suggestion proposes geocoding addresses via a map API but does not mention consent, provider trust, or disclosure that location/address data will be transmitted to a third party. In a personal travel database, stored places and addresses can be sensitive, so silent enrichment through an external API creates a real privacy and data-handling risk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The Bing fallback sends the raw user query to an external search engine without any notice, consent, or minimization. In this skill context, queries may contain private travel plans, locations, preferences, or notes from a personal knowledge base, so silent transmission materially increases privacy risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The code persistently stores user location queries and search results to a local JSON file for up to 30 days, but there is no consent, warning, or privacy control in this component. In a travel assistant context, these queries can reveal sensitive patterns such as home/work locations, travel plans, habits, and personal preferences, so unannounced retention creates a real privacy risk if the device is shared, compromised, or backed up to less-trusted storage.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The function sends the user-provided location query directly to DuckDuckGo, disclosing potentially sensitive travel interests or whereabouts to a third-party service without an explicit privacy warning or consent flow. In a personal travel assistant context, queries may reveal home addresses, hotels, planned trips, or private preferences, so even routine network lookup creates a real but low-severity privacy leak.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The helper persists values directly into the project .env file, which is commonly used for secrets such as NOTION_TOKEN. Storing secrets in a plaintext repo-adjacent file increases risk of accidental disclosure through source control, backups, local compromise, or overly broad file permissions.

Credential Access

High
Category
Privilege Escalation
Content
def save_local_env_value(key: str, value: str) -> None:
    """Set one value in project .env without printing or touching other secrets."""
    env_path = project_root() / ".env"
    lines = env_path.read_text(encoding="utf-8").splitlines() if env_path.exists() else []
    updated = False
Confidence
86% confidence
Finding
This function explicitly writes values into the project's .env file, which can include API credentials. Plaintext secret persistence in a workspace file creates a realistic exposure path through commits, logs, backups, shared folders, or multi-user systems.

Credential Access

High
Category
Privilege Escalation
Content
def save_local_env_value(key: str, value: str) -> None:
    """Set one value in project .env without printing or touching other secrets."""
    env_path = project_root() / ".env"
    lines = env_path.read_text(encoding="utf-8").splitlines() if env_path.exists() else []
    updated = False
    new_lines: list[str] = []
Confidence
79% confidence
Finding
Opening and updating the .env file here participates in secret persistence rather than mere configuration reading. In a travel-sync skill that handles third-party API tokens, this increases the chance that credentials are unintentionally retained in an insecure local artifact.

Static analysis

No suspicious patterns detected.