Back to skill

Security audit

Surf Query

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it includes an unsafe self-updater and disables HTTPS certificate checks while using an API key.

Review before installing. The surf lookup behavior is coherent, but do not use the bundled updater unless it is changed to verify signed or pinned releases, and avoid using the live CWA features on untrusted networks until TLS verification is restored. Treat optional cron notifications and parking integration as opt-in features that should be scoped to known recipients and trusted local skills.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
update.sh:5
Finding

Unverified Remote Code Replaces the Installed Skill Executable

Content
View full analysis
/dev/null | awk '{print $3}') if [ -z "$REMOTE_VER" ]; then exit 0 fi if [ "$LOCAL_VER" = "$REMOTE_VER" ]; then exit 0 fi curl -sf "$REPO_URL/raw/main/surf_query.py" -o "$CURRENT.tmp" && \ mv "$CURRENT.tmp" "$CURRENT" && \ curl -sf "$REPO_URL/raw/main/skill.yml" -o "$SKILL_DIR/skill.yml.tmp" && \ mv "$SKILL_DIR/skill.yml.tmp" "$SKILL_DIR/skill.yml" && \ curl -sf "$REPO_URL/raw/main/taiwan_surf_spots.json" -o "$SKILL_DIR/taiwan_surf_spots.json.tmp" && \ mv "$SKILL_DIR/taiwan_surf_spots.json.tmp" "$SKILL_DIR/taiwan_surf_spots.json" ``` ### Technical Analysis The update script downloads `surf_query.py` directly from the mutable `main` branch of an external GitHub repository and replaces the installed executable. It does not pin an immutable commit, verify a cryptographic checksum, validate a digital signature, or inspect the downloaded Python file before installation. The version comparison does not provide security. Both the version identifier and the executable are controlled by the same remote source, so an attacker controlling that source can publish any version string and arbitrary Python code. HTTPS protects the connection only while the remote repository and certificate trust chain remain uncompromised; it does not establish that the downloaded artifact is an approved release. The project documentation instructs users to execute this updater, and the script comments indicate that it may be called by weekly maintenance automati ...[truncated 1530 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
surf_query.py:168
Finding

TLS Certificate Verification Is Disabled While Transmitting an API Key

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Third-Party Dependency Is Installed Without Reproducible Version or Integrity Pinning

Content
View full analysis
=2.28.0 ``` Related installation guidance in `README.md:61-65` and `SKILL.md:63-66` installs the latest available package directly: ```bash pip3 install requests ``` ### Technical Analysis The requirement specifies only a lower version boundary. Consequently, any current or future release satisfying `requests>=2.28.0` may be installed. No lockfile, exact version, package hash, or authenticated artifact constraint is provided. This makes installations non-reproducible and prevents operators from confirming that they are installing the same dependency version reviewed during the skill audit. A future compromised release, package-index compromise, or incompatible upstream change would automatically enter the accepted dependency range. The package name is legitimate and there is no evidence that the currently referenced `requests` package is malicious. The risk arises from unrestricted future resolution and the absence of artifact-level integrity controls. ### Attack Path 1. A user installs the project's requirements or follows the documented `pip3 install requests` command. 2. The package resolver selects the newest release available from the configured package index because no exact reviewed version is required. 3. A compromised index, compromised upstream release process, or maliciously modified accepted release supplies an artifact satisfying the broad version constraint. 4. Pip downloads and installs that artifact without comparing it against a project-maintained expected hash. 5. Malicious package installation behavior may execute during installation, or malicious runtime behavior may execute when `surf_query.py` imports `requests`. ### Impact Assessment A compromised dependency can execute with the privileges of the user p ...[truncated 427 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A surf-information skill should not self-update from a remote GitHub repository, fetch remote code/data for replacement, or modify its own local files unless this behavior is explicitly declared and strongly secured. This creates a supply-chain and remote code execution risk: a compromised repository, MITM, or malicious update path could silently alter the skill after installation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A surf-information skill should not self-update from a remote GitHub repository, fetch remote code/data for replacement, or modify its own local files unless this behavior is explicitly declared and strongly secured. This creates a supply-chain and remote code execution risk: a compromised repository, MITM, or malicious update path could silently alter the skill after installation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file implements a remote code update mechanism unrelated to the declared purpose of querying surf spots, tides, and nearby parking. Such hidden or unjustified code replacement capability increases risk because it can silently alter future behavior of the skill without user awareness, turning any upstream compromise into persistent local compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README explicitly encourages scheduled push notifications to Telegram, LINE, and iMessage, including typhoon alerts and daily reports, but does not warn about proactive outbound messaging, recipient targeting, consent, rate limits, or privacy implications. In an agent ecosystem, this can lead to unreviewed background messaging behavior, accidental disclosure to unintended recipients, or notification abuse if schedules or bindings are misconfigured.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
97% confidence
Finding

The example code disables TLS certificate verification with verify=false when calling the CWA API. That permits man-in-the-middle interception or tampering of API responses, which is especially risky in scheduled alerting logic because falsified weather or typhoon data could trigger misleading notifications or suppress real alerts.

Content

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

md
r = requests.get(
    "https://opendata.cwa.gov.tw/api/v1/rest/datastore/W-C0034-005",
    params={"Authorization": KEY},
    verify=False  # CWA 憑證缺 SKI,Python 3.12+ 需加此參數
)
data = r.json()
cyclones = data["records"]["TropicalCyclones"]["TropicalCyclone"]

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
97% confidence
Finding

This second example repeats verify=false for another CWA endpoint, again disabling HTTPS certificate validation. Even though it appears in README sample code, users commonly copy-paste such snippets into production automations, making insecure transport a likely real deployment risk.

Content

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

r = requests.get( "https://opendata.cwa.gov.tw/api/v1/rest/datastore/W-C0051-001", params={"Authorization": KEY}, verify=False )

text

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documentation and manifest declare no explicit tool scope or permissions, yet the analyzed capability set indicates environment-variable access, network access, and shell/subprocess use. This is dangerous because users and the platform cannot accurately constrain or review what the skill may do, increasing the risk of unexpected network calls, command execution, or abuse of sensitive environment data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill name, description, examples, and usage instructions are entirely written in Traditional Chinese and target Taiwan-specific usage, but there is no natural-language statement that this language choice is optional or that the skill is restricted to Chinese-speaking users. Under the policy rule, forcing a specific language without user opt-in can be a locale/language policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger patterns are very broad: single words like "衝浪", "浪點", and especially "surf" can appear in ordinary conversation and unintentionally activate the skill. In an agent environment, this can cause inappropriate tool invocation, unexpected processing of user messages, and accidental disclosure or use of location-related functionality without clear user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill disables TLS certificate verification and suppresses the associated warnings before sending authenticated requests containing the CWA API key. This permits man-in-the-middle interception or response tampering, which is especially risky because the skill trusts remote weather and typhoon data that may influence user decisions.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
98% confidence
Finding

Using verify=False makes HTTPS transport unauthenticated, allowing attackers on the network path to impersonate the CWA endpoint or alter returned data. Because this request includes an API credential and feeds user-visible operational data, the unsafe default has meaningful confidentiality and integrity consequences.

Content

Scanner excerpt · surf_query.py (reported line 172)May include surrounding context.

python
return None
    try:
        params["Authorization"] = key
        # verify=False: CWA 憑證缺 Subject Key Identifier,Python 3.14 拒絕
        import urllib3
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        r = requests.get(f"{CWA_BASE}/{dataset}", params=params, timeout=8, verify=False)

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
97% confidence
Finding

This finding is the same insecure request path where certificate verification is disabled, creating a persistent insecure default for all CWA API fetches. The context makes it more dangerous because multiple features depend on this helper, so all tide, wind, and typhoon lookups inherit the same MITM exposure.

Content

Scanner excerpt · surf_query.py (reported line 175)May include surrounding context.

python
# verify=False: CWA 憑證缺 Subject Key Identifier,Python 3.14 拒絕
        import urllib3
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        r = requests.get(f"{CWA_BASE}/{dataset}", params=params, timeout=8, verify=False)
        d = r.json()
        return d if d.get("success") == "true" else None
    except Exception:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This surf lookup skill includes a broader capability to execute an external parking-query skill, which is beyond simple data retrieval and increases attack surface. In this context, the feature is user-facing and related, but the implementation still creates an unnecessary code-execution dependency on another local component that may be modified independently.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The code executes another local skill via subprocess based on a fixed path under the user's home directory. Although it does not use shell=True and the lat/lon arguments are converted to floats, this still expands the skill's trust boundary: if that external script or the selected interpreter is replaced or tampered with, this skill will execute untrusted code with the current user's privileges.

Content

Scanner excerpt · surf_query.py (reported line 316)May include surrounding context.

python
if not parking_script.exists():
        return "(停車查詢 skill 未安裝)"
    try:
        result = subprocess.run(
            [python, str(parking_script), "--lat", str(lat), "--lon", str(lon), "--mode", "realtime"],
            capture_output=True, text=True, timeout=30
        )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The notes explicitly specify county names as '臺灣正體', and the dataset consistently uses Chinese-language fields and locale-specific naming without any indication that language choice is optional. Under the policy, forcing a specific language or locale without user opt-in can be a natural-language policy violation unless the constraint is clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script downloads executable skill code and related files from a remote repository and replaces local copies in-place, effectively granting the repository ongoing code execution influence over the installed skill. For a surf-information skill, this updater is outside the expected user-facing function and creates a supply-chain risk if the repository, account, network path, or upstream content is compromised.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script performs network downloads and overwrites local files automatically with no confirmation, disclosure, integrity validation, or dry-run step. This enables silent changes to code and data, making accidental corruption, malicious upstream tampering, or unexpected behavior much harder for operators to detect before installation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The natural-language instructions and examples in this file consistently assume Traditional Chinese, but there is no opt-in, alternative language option, or explicit statement that the skill is intentionally Taiwan-specific. Under the language/locale policy, forcing a specific language without user choice can be a policy concern unless the locale constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified as requests>=2.28.0, which allows any newer release to be installed and makes builds non-reproducible. This can unintentionally introduce breaking changes or vulnerable versions over time, and it also prevents auditors from knowing exactly what version is deployed.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.28.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

Because requests is not pinned, it is impossible to verify whether the deployed version includes fixes for known advisories affecting older releases. In a skill that may call external services for tide, weather, typhoon, parking, or messaging integrations, use of an affected HTTP client could expose credentials, weaken TLS verification behavior, or leak sensitive request data depending on the vulnerable version actually installed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest describes the skill as limited to Taiwan surf spots and primarily uses Traditional Chinese, with only one English trigger, but it does not state that this locale/language restriction is optional or justified as a region-specific compliance requirement. This can be interpreted as a locale policy issue because the user is not offered a language or locale choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

Natural-language strings, comments, help text, and usage are presented in Chinese and scoped to Taiwan, but the skill does not indicate that this locale/language is optional or user-selectable. Under the stated policy, forcing a specific language without user opt-in is a locale-policy issue.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stated purpose is surf spot and weather-related querying, and network access to CWA is expected, but directly reading credentials from environment variables is a separate sensitive capability. The manifest does not mention secret or credential access, so this is an unjustified capability relative to the declared user-facing purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

All user-facing comments and echo messages are written only in Traditional Chinese, with no indication that another language can be selected. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.