Back to skill

Security audit

smart-site-selection-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its site-selection purpose, but it has review-worthy security weaknesses around API key exposure, unsafe HTML report generation, broad triggers, silent installs, and uncontrolled file writes.

Install only in an isolated environment with a restricted AMap key. Do not share generated reports unless the key has been removed or replaced, and treat report contents as unsafe HTML until escaping, filename sanitization, dependency pinning, and clearer user consent are added.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/report_builder.py:14
Finding

Stored HTML and JavaScript Injection in Generated Reports

Content
View full analysis
Top {i+1} {loc['name']}
{loc['transit']} 个
如:{loc['transit_short']}
{loc['office']} 个
{loc['competitors']} 家
{loc['score']} 分 """ micro_insights_html = "" detailed_pois_html = "" for i, loc in enumerate(locations_data): micro_insights_html += f"""

📍 Top {i+1} : {loc['name']}

{loc['micro_insight']}

""" office_tags = "".join( [f"{name}" for name in loc['office_list']] ) or "暂无核心设施" comp_tags = "".join( [f"{name}" for name in loc['comp_list']] ) or "暂无直接竞品" ``` The macro insight is also inserted directly into the document: ```python
{macro_insight}
``` Location data is additionally serialized inside an executable script element: ```python
Remediation
View remediation
` element after safely escaping `<`, `>`, `&`, U+2028, and U+2029. - Load data from a separate local JSON resource. - Use a framework-provided safe JSON serialization mechanism. 4. Escape at least the following characters in script-embedded JSON: ```python safe_json = json.dumps(data, ensure_ascii=False) safe_json = ( safe_json .replace("&", "\\u0026") .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("\u2028", "\\u2028") .replace("\u2029", "\\u2029") ) ``` 5. Add a restrictive Content Security Policy. Avoid allowing inline scripts where feasible, and restrict network destinations to the minimum required domains. 6. Add regression tests using payloads containing HTML event handlers, quotation marks, ``, and Unicode line separators. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/report_builder.py:9
Finding

AMap Web Service API Key Embedded in Generated HTML

Content
View full analysis
📍 Top 3 选址空间锚点映射
``` ### Technical Analysis The `AMAP_WEBSERVICE_KEY` is passed to the report builder and inserted directly into an image URL. Because the complete URL is written into a persistent HTML file, the key is no longer confined to the server-side process environment. Any recipient who receives the report can inspect the HTML source or image URL and extract the credential. Depending on how the report is hosted or shared, URLs may also be recorded in browser history, HTTP logs, monitoring systems, screenshots, or document archives. The use of HTTPS protects the key while it is transported to AMap, but it does not prevent disclosure to users who can access the generated document. ### Attack Path 1. A valid AMap Web Service key is supplied to `run_selection_engine`. 2. `generate_html_report` embeds that key in `static_map_url`. 3. The generated HTML file is saved and shared with a user or placed on a web server. 4. A recipient inspects the document source or observes the static-map request. 5. The recipient copies the `key` query parameter. 6. The exposed key is reused to make unauthorized AMap API requests until it is revoked or its restrictions prevent misuse. ### Impact Assessment An attacker does not gain local system privileges, but obtains the effective p ...[truncated 448 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/site_selection_engine.py:93
Finding

User-Controlled Report Name Permits Writes Outside the Intended Directory

Content
View full analysis
Remediation
View remediation
str: value = re.sub(r"[^A-Za-z0-9_-]+", "_", value) value = value.strip("._-") if not value: raise ValueError("Invalid report filename component") return value[:80] filename = ( f"{safe_component(city)}_" f"{safe_component(keyword)}_commercial_report.html" ) output_path = (REPORT_DIR / filename).resolve() report_root = REPORT_DIR.resolve() if report_root not in output_path.parents: raise ValueError("Output path escapes the report directory") ``` 4. Use exclusive creation mode (`"x"`) or a securely generated unique filename if overwriting reports is not required. 5. Keep the human-readable city and keyword values separate from filesystem path components. 6. Add tests for absolute paths, `../`, backslashes, repeated separators, reserved names, null bytes, and Unicode separator lookalikes. ]]>

T08 · Insecure Dependencies

Warning
Location
package.json:23
Finding

Unpinned and Ecosystem-Confused Dependency Installation

Content
View full analysis
Remediation
View remediation
--hash=sha256: ``` 4. Remove `matplotlib` if it is not used by the executable source code. 5. Use a lockfile generated from a trusted package index and verify it in source control. 6. Avoid silent runtime package installation. Dependency installation should be an explicit deployment step with visible package names, versions, registries, and integrity verification. 7. Disable or restrict package lifecycle scripts where practical, and perform installation using a least-privileged isolated environment. 8. Add automated dependency review, vulnerability scanning, and checks that reject unpinned or cross-ecosystem dependency declarations. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README mentions API key setup and generated HTML reports, but it does not clearly warn users that the skill will perform external network requests to Gaode and possibly other services, nor that it will create output files during execution. Lack of transparent disclosure weakens informed consent and can surprise users in restricted or sensitive environments where network egress and file creation are security-relevant events.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README says users can 'directly ask the Agent' about opening a store to trigger the skill, which is a broad invocation description rather than a narrowly scoped activation condition. In an agent environment, vague triggers can cause unintended execution, leading to unnecessary external API calls, data gathering, and report generation when the user did not explicitly consent to those actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The description is written as a Chinese-only skill experience and the interaction templates and workflow are all specified in Chinese, with no indication that users may choose another language. This can violate language or locale policy when a skill imposes a specific language without user opt-in or a documented region-specific justification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger terms are very broad, so the skill may activate on generic conversations about business insights or opening a store even when the user did not intend to invoke this workflow. Unintended activation can cause unnecessary data access, unsolicited follow-up prompts, or downstream report-generation behavior that surprises the user.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Lines L043-L046 explicitly state the agent must only retrieve three coordinates and are framed as a strict prohibition against querying transport stations, office buildings, or competitor counts. However, later lines L083 and L095-L107 describe the skill's Python engine performing those exact data grabs as part of the same skill workflow, which contradicts the earlier 'absolute prohibition' framing rather than merely adding omitted detail.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

Lines L052-L053 describe a handoff model where the AI stops after preparing coordinates and text for a separate backend engine. But the document's example and output specification later include Python execution for data fetching, scoring, HTML generation, and file output as part of the skill's end-to-end behavior, blurring whether those actions are external or intrinsic to this skill.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The top-level documentation says this is a 'Smart Site Selection' entry script that will first ask follow-up questions and then generate a report. In code, after parameter checks, it only prints guidance about required parameters for a separate engine and references another file, without actually calling run_selection_engine or producing a report.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring and all user-facing prompts are written exclusively in Chinese, and the workflow expects Chinese keyword matching for required parameters. This effectively forces a specific language/locale without user opt-in, which matches the policy-violation category for language or locale constraints.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This manifest file defines generic triggers such as “调查报告”, “开店”, and “商业洞察” without any narrowing context or exclusion conditions. Because these phrases can appear in ordinary conversation and many unrelated business requests, the skill may activate unintentionally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The generated HTML embeds a third-party map URL containing both precise location markers and the AMap API key directly in the page. When the report is opened, the client browser will send this data to the external provider, which can leak sensitive business location analysis and expose the key to anyone who can view or inspect the report.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The HTML declares lang="zh-CN" and hard-codes Chinese-language titles/content throughout the generated report. This imposes a specific language/locale on all users with no opt-in, choice, or documented regional justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code sends precise longitude/latitude, search keywords, and business-intent data to a third-party mapping API. In a site-selection context, this can expose sensitive location intelligence or user/business planning data without any visible consent, minimization, or disclosure mechanism in this component.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill README presents all operational instructions and examples exclusively in Chinese, which can amount to a language-policy issue when no user language choice or opt-in is provided. There is no indication that the skill is region-locked or otherwise justified as Chinese-only.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill specifies creating an HTML report in the current working directory without clearly notifying the user at execution time or obtaining consent. Silent file creation can lead to workspace pollution, accidental overwrites, or unexpected persistence of potentially sensitive business-analysis data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The package description is entirely Chinese and does not indicate that users may choose another language or that the skill is intentionally limited to a Chinese-speaking region. Under the policy, forcing a specific language without opt-in can be a natural-language policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
82% confidence
Finding

Using a caret range for matplotlib allows future minor/patch releases to be installed without explicit review, which can introduce supply-chain risk or unexpected behavior changes. In a skill that depends on Python packages and may run in automated environments, unpinned dependencies reduce build reproducibility and increase exposure if an upstream release is compromised.

Content

Scanner excerpt · package.json (reported line 24)May include surrounding context.

json
"node": ">=14"
  },
  "dependencies": {
    "matplotlib": "^3.5.0",
    "requests": "^2.28.0"
  },
  "openclaw": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
84% confidence
Finding

Using a caret range for requests permits automatic adoption of newer upstream releases, creating a supply-chain and reproducibility risk. Because requests is a network-facing library and this skill appears to fetch external data, an unexpected or compromised dependency update could have broader operational impact than a purely local library.

Content

Scanner excerpt · package.json (reported line 25)May include surrounding context.

json
},
  "dependencies": {
    "matplotlib": "^3.5.0",
    "requests": "^2.28.0"
  },
  "openclaw": {
    "type": "skill",

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The function writes generated HTML to the path provided by output_filename, which can overwrite or create files on disk. In this file there is no confirmation prompt, logging/print statement, or docstring/comment disclosing that a filesystem write occurs.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The run_selection_engine docstring frames the function as a data-query entrypoint, but the function also sorts results, generates an HTML report, and returns the output file path via generate_html_report at L93-L95. This is an intent-level mismatch in documentation because the documented role is narrower than the actual side effect of report creation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The code generates and saves a report file, and only informs the user after creation is complete. There is no prior confirmation, warning comment, or docstring in this file indicating that running the skill will create an output file on disk.

Content

No source excerpt is available for this finding.