Back to skill

Security audit

baidu-mapbox-isochrone

Security checks for vulnerabilities and agentic risk

Overview

The skill performs the advertised map generation, but it mandates sending precise location artifacts externally and handles API keys in ways users should review before installing.

Install only if users are comfortable sending addresses, precise coordinates, shapefiles, imagery, and previews to Baidu, Mapbox, ESRI, and a Feishu destination. Before use, require explicit approval before any message/file send, confirm the recipient, use scoped environment variables or a secret manager for API keys, avoid command-line secrets, and install dependencies in a pinned virtual environment.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:62
Finding
Persistent Agent Memory Access for API Credentials<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:62-63, 97-98` **Vulnerability Type**: Access to persistent Agent state for secret retrieval **Risk Level**: Medium ### Evidence ```markdown | 2 | 百度 AK | 百度地图开放平台 AK | MEMORY.md 中已存储 | | 3 | Mapbox AK | Mapbox 访问令牌 | MEMORY.md 中已存储 | ``` ```markdown ## API 密钥 - 百度 AK:MEMORY.md → `百度AK` 字段 - Mapbox AK:MEMORY.md → `Mapbox AK` 字段 ``` ### Technical Analysis The Skill directs the Agent to inspect `MEMORY.md` and extract two reusable API credentials. This expands the Skill's access beyond the mapping operation into persistent Agent state. Reading a general-purpose memory file is broader than the minimum privilege required because the script could instead receive narrowly scoped credentials from a secret manager or protected environment variables. If memory access is not technically restricted to the named fields, loading the file may also expose unrelated persistent data to the Agent context, execution logs, or downstream tooling. ### Attack Path 1. A user invokes the isochrone Skill without explicitly supplying credentials. 2. The Skill instructions direct the Agent to open `MEMORY.md`. 3. The Agent reads the Baidu and Mapbox credentials into its working context. 4. The credentials may subsequently appear in generated commands, process metadata, Agent telemetry, or logs. 5. A party with access to those surfaces can recover and reuse the credentials against the corresponding APIs. ### Impact Assessment Successful exposure provides the ability to use the affected Baidu or Mapbox account within the permissions and quotas assigned to each token. Consequences can include unauthorized API consumption, quota exhaustion, billing impact, and access to any other API functions enabled for those credentials. No evidence indicates that the Skill writes to memory or establishes persistence. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove instructions that require opening or parsing `MEMORY.md`. 2. Retrieve credentials through a scoped secret manager that returns only the specifically requested secret. 3. Alternatively, read the credentials from protected environment variables such as `BAIDU_MAP_AK` and `MAPBOX_ACCESS_TOKEN`. 4. Ensure the Agent never prints, interpolates, or returns secret values in messages. 5. Use restricted API tokens with minimum scopes, origin restrictions, usage limits, and expiration where supported. 6. Rotate credentials that may previously have been exposed through Agent context or logs. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_isochrone.py:536
Finding
API Credentials Exposed Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:88-91`; `scripts/generate_isochrone.py:536-544` **Vulnerability Type**: Insecure secret handling through process arguments **Risk Level**: Medium ### Evidence ```bash python3 /root/.openclaw/workspace/skills/baidu-mapbox-isochrone/scripts/generate_isochrone.py "天津市南楼煎饼" "<百度AK>" "<MapboxAK>" "walking" 15 ``` ```python def main(): if len(sys.argv) < 6: print("用法: python generate_isochrone.py <地址> <百度AK> <MapboxAK> <出行模式> <时间(分钟)> [输出目录]") sys.exit(1) address = sys.argv[1] baidu_ak = sys.argv[2] mapbox_ak = sys.argv[3] mode = sys.argv[4].lower() minutes = int(sys.argv[5]) output_dir = sys.argv[6] if len(sys.argv) > 6 else "/root/.openclaw/workspace/isochrone_output" ``` ### Technical Analysis Both API credentials are supplied as positional command-line arguments. Process arguments can be visible in process inspection interfaces and may be retained by shell history, orchestration telemetry, Agent tool-call records, audit logs, or crash diagnostics. The script subsequently sends the credentials to the intended official services over HTTPS. That network use is necessary for the declared functionality, but exposing reusable credentials through `argv` is not necessary. ### Attack Path 1. The Agent reads or receives the Baidu and Mapbox credentials. 2. It constructs the command documented in `SKILL.md`, embedding both credentials as plaintext arguments. 3. The operating system, shell, Agent runtime, or monitoring infrastructure records or exposes the process command line. 4. A local user or log reader obtains the argument values. 5. The attacker reuses the credentials against Baidu or Mapbox until they expire or are revoked. ### Impact Assessment The exposed values can grant unauthorized use of the APIs permitted by the relevant tokens. The scope is limited by token configuration, account restrictions, quotas, and provider-side controls. Potential eff ...[truncated 189 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the Baidu and Mapbox credentials from positional arguments. 2. Read them from protected environment variables or a scoped secret provider. 3. If environment variables are not available, accept credentials through standard input without echoing them. 4. Redact authorization query parameters from request logs, exceptions, and telemetry. 5. Avoid command examples that encourage plaintext secret interpolation. 6. Restrict token scopes, quotas, allowed origins or IP addresses, and expiration periods. 7. Rotate any credentials previously invoked through command-line arguments on shared or monitored systems. ]]>

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:29
Finding
Mandatory External Transmission of Sensitive Location Artifacts<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:29-53` **Vulnerability Type**: Unconditional external delivery instruction **Risk Level**: Medium ### Evidence ```markdown ## ⚡ 自动发送流程(必须执行) 脚本成功后将触发自动发送,agent 必须执行以下步骤: ### Step A: 打包所有产物 ```bash cd <output_dir> zip <名称>.zip point.shp point.shx point.dbf point.prj point.cpg \ isochrone.shp isochrone.shx isochrone.dbf isochrone.prj isochrone.cpg \ base_map_wgs84.tif isochrone_preview.jpg ``` ### Step B: 发送预览图(通过 message 工具) ``` action: send channel: feishu message: 📍 <地址> · <N>分钟<出行模式>等时圈\n\n🗺️ WGS84坐标:<lng>, <lat>\n覆盖范围:<描述> media: <preview_jpg路径> ``` ### Step C: 发送 ZIP 文件包(通过 message 工具) ``` action: send channel: feishu message: 📦 SHP全套文件包(含.shp/.shx/.dbf/.prj/.cpg + 底图TIFF + 高清预览图) filePath: <zip路径> ``` ``` ### Technical Analysis The Skill states that external sending is mandatory and directs the Agent to use the messaging tool with a fixed Feishu channel. The transmitted content includes the supplied address, precise WGS84 coordinates, point and isochrone shapefiles, satellite imagery, and a preview. Returning generated artifacts to the requesting user can be a legitimate feature. However, the instructions do not require explicit confirmation before transmission, do not identify or validate the recipient, and do not provide a local-only default. Consequently, sensitive location artifacts could be delivered through an unintended account, conversation, or recipient context. The Python script itself does not implement this transmission. The risky behavior exists in the Agent instructions. ### Attack Path 1. A user supplies a sensitive home, workplace, facility, or other location. 2. The script geocodes the address and creates precise location artifacts. 3. The Agent follows the mandatory packaging instruction and bundles all generated files. 4. Without obtaining per-send approval or validating a recipient, the Agent invokes the messaging tool using the Feishu channel. 5. Th ...[truncated 706 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace mandatory automatic sending with local artifact generation by default. 2. Obtain explicit user confirmation immediately before each external transfer. 3. Display the destination, recipient, included files, and sensitive metadata before sending. 4. Require the user to select or confirm the destination rather than relying on an implicit Feishu context. 5. Allow users to exclude the GeoTIFF, precise point layer, address, or coordinate text. 6. Apply data-minimization controls, such as coordinate rounding or omission of the exact starting point. 7. Record consent and delivery status without logging credentials or unnecessarily retaining location data. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:103
Finding
Unpinned System-Wide Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:103-108` **Vulnerability Type**: Unsafe dependency installation guidance **Risk Level**: Medium ### Evidence ```markdown ## 错误处理 | 错误 | 原因 | 处理 | |------|------|------| | 百度地理编码失败 | AK 无效或地址无法识别 | 检查 AK / 换用更精确的地址 | | Mapbox API 认证失败 | Mapbox AK 错误 | 核对 AK | | Mapbox API 参数错误 (422) | 坐标超出支持区域 | 确认地址在支持范围内 | | 依赖缺失 | 包未安装 | `pip install coord_convert geopandas shapely pyshp matplotlib --break-system-packages` | ``` ### Technical Analysis The documented installation command uses unpinned package names from the configured Python package index and includes `--break-system-packages`. Unpinned dependencies make builds non-reproducible and permit future package releases to alter the effective code executed by the Skill. The override flag bypasses protections intended to prevent modifications to a distribution-managed Python environment. The repository does not provide a lock file, hash verification, isolated environment instructions, or provenance controls for these dependencies. ### Attack Path 1. The Skill fails because one or more dependencies are absent. 2. The Agent or operator follows the documented installation command. 3. The package resolver downloads the currently selected package versions from its configured index. 4. A compromised release, malicious index configuration, dependency-confusion package, or unexpectedly incompatible update is installed. 5. Installation hooks or imported package code executes with the privileges of the Agent process. 6. Because `--break-system-packages` is used, the installation may also overwrite or conflict with system-managed packages. ### Impact Assessment A malicious dependency can execute arbitrary Python code with the permissions of the installing or invoking account. This may permit access to files, environment variables, API credentials, generated location artifacts, and available network resources. Even without a malicious package, incompatible ...[truncated 235 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--break-system-packages`. 2. Install dependencies inside a dedicated virtual environment or isolated container. 3. Provide a lock file with reviewed, exact package versions. 4. Use cryptographic hashes with `pip --require-hashes` where practical. 5. Configure an approved package index and verify package ownership and provenance. 6. Include every runtime dependency in the lock file, including geospatial and raster-processing libraries. 7. Regularly scan locked dependencies for known vulnerabilities and update them through a controlled review process. 8. Run the Skill under a non-privileged account with restricted filesystem and network access. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill mandates automatic transmission of a preview image, ZIP archive, and user-derived location details to an external channel without any per-run confirmation. This creates a direct exfiltration path for sensitive geolocation data and generated files, especially if the invoking user did not explicitly request outbound sharing or if the destination channel is wrong.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill clearly performs outbound network operations to Baidu, Mapbox, and likely tile servers, but it declares no explicit tool scope or permissions boundary. That increases the chance the agent can invoke broader network access than intended, weakening least-privilege controls and making misuse or accidental data disclosure harder to prevent.

Ssd 3

Medium
Confidence
97% confidence
Finding
The skill instructs the agent to package and transmit all generated files and location-derived metadata automatically, including shapefiles, a TIFF basemap, and a preview image. Because these artifacts encode sensitive user-request data and are sent without explicit consent checks, the behavior materially increases privacy and data-leakage risk.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill instructs the agent to retrieve API keys from MEMORY.md without any warning, scoping, or approval flow for credential access. Unconstrained secret retrieval increases the risk of exposing stored credentials to the model context, logs, downstream tools, or unintended outputs.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script sends user-supplied addresses and derived coordinates to Baidu and Mapbox without any explicit consent, warning, or privacy notice. Because addresses and precise travel-origin points are sensitive location data, undisclosed third-party transmission can violate user expectations, internal policy, or privacy requirements.

External Transmission

Medium
Category
Data Exfiltration
Content
def geocode_baidu(address, ak):
    """调用百度地理编码API,返回第一个结果的 BD-09 坐标 (lng, lat)"""
    url = "https://api.map.baidu.com/geocoding/v3/"
    params = {"address": address, "ak": ak, "output": "json"}
    resp = requests.get(url, params=params, timeout=10)
    data = resp.json()
Confidence
95% confidence
Finding
This code transmits the user-provided address and API key to Baidu's geocoding service. In the context of an agent skill handling potentially sensitive addresses, external transmission is security-relevant because it shares location data with a third party and may create privacy/compliance exposure if undisclosed.

External Transmission

Medium
Category
Data Exfiltration
Content
"""调用 Mapbox Isochrone API,返回 GeoJSON FeatureCollection"""
    profiles = {"driving": "mapbox/driving", "walking": "mapbox/walking", "cycling": "mapbox/cycling"}
    profile = profiles.get(mode, "mapbox/driving")
    url = f"https://api.mapbox.com/isochrone/v1/{profile}/{wgs_lng},{wgs_lat}"
    params = {
        "access_token": mapbox_ak,
        "contours_minutes": str(minutes),
Confidence
95% confidence
Finding
This request sends precise WGS84 coordinates and the Mapbox access token to Mapbox's isochrone API. The transmission is expected for functionality, but it still represents sensitive location sharing that should be explicitly disclosed and governed.

External Transmission

Medium
Category
Data Exfiltration
Content
# Mapbox Static Images API — 底图 + 等时圈 GeoJSON 叠加
    # style: mapbox/streets-v12(街道图)
    base_url = "https://api.mapbox.com/styles/v1/mapbox/streets-v12/static"

    # 等时圈 GeoJSON 直接作为 overlay 传入(Mapbox 会在服务端渲染)
    overlay_part = f"geojson({json.dumps({'type': 'FeatureCollection', 'features': []})})"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# Mapbox Static Images API — 底图 + 等时圈 GeoJSON 叠加
    # style: mapbox/streets-v12(街道图)
    base_url = "https://api.mapbox.com/styles/v1/mapbox/streets-v12/static"

    # 等时圈 GeoJSON 直接作为 overlay 传入(Mapbox 会在服务端渲染)
    overlay_part = f"geojson({json.dumps({'type': 'FeatureCollection', 'features': []})})"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill manifest describes Baidu geocoding, coordinate conversion, and Mapbox isochrone generation, but the code also downloads ESRI imagery tiles and writes an additional GeoTIFF basemap. This hidden data flow and artifact creation increases privacy, compliance, and operational risk because users may not expect another third-party service to receive location-derived requests or an extra geospatial file to be stored.

Tainted flow: 'url' from requests.get (line 308, network input) → requests.get (network output)

Medium
Category
Data Flow
Content
row_tiles = []
        for tx in range(tx_min, tx_max + 1):
            url = f"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{ty}/{tx}"
            r = requests.get(url, timeout=request_timeout)
            if r.status_code == 200 and len(r.content) > 1000:
                img = Image.open(io.BytesIO(r.content)).convert("RGB")
            else:
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.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script saves point and isochrone shapefiles plus preview imagery containing location-derived data to disk without an explicit warning. On shared systems or agent environments, this can expose sensitive geospatial artifacts to other users, later tasks, or backup processes.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
plt.close()
            img = Image.open(png_tmp).convert('RGB')
            img.save(output_path, 'JPEG', quality=82, optimize=True)
            __import__('os').remove(png_tmp)
            size = __import__('os').path.getsize(output_path) // 1024
            print(f"  ✓ 已保存预览图(WGS84底图,JPG压缩{size}KB): {output_path}")
            return
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
img = Image.open(png_tmp).convert('RGB')
            img.save(output_path, 'JPEG', quality=82, optimize=True)
            __import__('os').remove(png_tmp)
            size = __import__('os').path.getsize(output_path) // 1024
            print(f"  ✓ 已保存预览图(WGS84底图,JPG压缩{size}KB): {output_path}")
            return
        except Exception as e:
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
plt.close()
    img = Image.open(png_tmp).convert("RGB")
    img.save(output_path, "JPEG", quality=75, optimize=True)
    __import__("os").remove(png_tmp)
    size_kb = __import__("os").path.getsize(output_path) // 1024
    print(f"  ✓ 已保存预览图(简洁WGS84网格背景,{size_kb}KB): {output_path}")
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
img = Image.open(png_tmp).convert("RGB")
    img.save(output_path, "JPEG", quality=75, optimize=True)
    __import__("os").remove(png_tmp)
    size_kb = __import__("os").path.getsize(output_path) // 1024
    print(f"  ✓ 已保存预览图(简洁WGS84网格背景,{size_kb}KB): {output_path}")

    """
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The dependency section states the system must install a Chinese font and names a specific CJK font for matplotlib use. This enforces a locale-specific rendering setup in natural language without indicating user opt-in or explaining why no language-neutral or user-selectable alternative is available.

Intent-Code Divergence

Low
Confidence
99% confidence
Finding
The top-level docstring explicitly claims `预览图.png` as an output artifact. Later code saves the final preview as JPEG, so the inline documentation contradicts actual behavior rather than merely omitting detail.

Description-Behavior Mismatch

Low
Confidence
98% confidence
Finding
The module docstring states the output includes `预览图.png`, but both preview-generation branches save a temporary PNG and then convert it to a final JPEG at the requested output path. The main routine also names the final file `isochrone_preview.jpg`, so the observed behavior does not match the documented output format.

Static analysis

No suspicious patterns detected.