Back to skill

Security audit

geoskill-lidar-canopy-structure

Security checks across malware telemetry and agentic risk

Overview

The documented LiDAR workflow is mostly local, but the package also ships under-disclosed network and credential-handling helpers that do not fit the offline privacy claim.

Install only after reviewing or removing the unused geocoding, download, and credential modules, especially credentials.py. Treat the offline/no-network claim as inaccurate for the full package, and use a constrained environment if testing it.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (21)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares an entirely offline LiDAR workflow, yet the analyzed capabilities indicate access to environment variables, filesystem I/O, shell execution, and network functions without corresponding permission disclosure. That mismatch creates a trust and containment problem: users may run the skill expecting local-only processing while it can access sensitive local data or communicate externally.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This is a strong description-behavior mismatch: the skill presents itself as an offline canopy-analysis tool, but the detected behavior includes online geocoding/weather lookups, caching to the user home directory, generic HTTP downloading, credential harvesting from environment/.netrc/secrets files, and even embedded default Earthdata credentials. Those hidden capabilities materially expand the attack surface and could expose secrets, exfiltrate data, or perform unexpected remote fetches under the guise of a local geospatial workflow.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The vendored core metadata claims the embedded core belongs to a different skill ('landsat-download') than this package's stated lidar canopy analysis purpose. This creates a supply-chain integrity problem: provenance, review status, and compatibility of the vendored core cannot be trusted, which can conceal accidental or malicious code substitution and mislead downstream validation tooling.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
This module performs outbound requests to Open-Meteo and Nominatim to resolve place names, which is an undeclared capability relative to a LiDAR canopy-analysis skill. Even if functionally useful, third-party network access can leak user-supplied place names, introduce dependency on external services, and expand the attack surface through unexpected data exfiltration and availability risks.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The module persists cached AOI query results under the user's home directory, which is a side effect not described by the skill. Persistent local storage can retain sensitive or private location queries beyond the session, creating privacy and data-governance concerns, especially on shared systems.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Contacting third-party geocoding services is context-inappropriate for a skill described as LiDAR canopy structure analysis unless explicitly disclosed. The danger is not code execution but unannounced transfer of user input and workflow metadata to external providers, which can violate least-privilege expectations and privacy constraints.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
This credential manager hardcodes a real-looking Earthdata username/password fallback and exposes helpers for multiple unrelated third-party services (OpenAI, CMA, FIRMS, EOG) despite the skill being declared as lidar canopy analysis. Broad secret-access capability plus embedded fallback credentials violates least privilege and creates a strong risk of unauthorized account use or credential abuse if any downstream code invokes these helpers.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The code reads from the user's home directory and environment to harvest credentials from ~/.geoskill/secrets.json and ~/.netrc/_netrc for several services. In a lidar-analysis skill, this broad credential discovery is not clearly justified, so it increases the blast radius: installing or running the skill grants it access to secrets unrelated to its stated purpose.

Description-Behavior Mismatch

High
Confidence
93% confidence
Finding
The exported resolve_place() API introduces place-name resolution and network-capable AOI lookup in a skill whose declared purpose is LiDAR canopy-structure analysis. Even if not overtly malicious, this creates unnecessary external data flow, expands attack surface, and can transmit user-provided locations to third-party services or fallback code paths that the user may not expect.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The code makes outbound HTTP requests to external geocoding providers (Open-Meteo and Nominatim) using user-supplied place names. In the context of a canopy-analysis skill, these requests are not clearly justified, can leak sensitive or proprietary AOI information to third parties, and create dependency on remote services for a capability outside the stated purpose.

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
In synthetic mode, the supplied geographic bbox is not used for analysis of the generated point cloud; it is only reused later to georeference outputs. This creates a semantic mismatch between documented behavior and actual processing, which can cause downstream users to trust spatial extents, locations, or resolution relationships that were never enforced during analysis.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The code writes GeoTIFF and GeoJSON outputs with CRS EPSG:4326 even when the input point cloud may be in arbitrary local/projected coordinates. This can silently mislabel non-geographic data as WGS84, leading to severe spatial misregistration, incorrect overlays, and unsafe downstream decisions if the outputs are consumed as real geospatial products.

Credential Access

High
Category
Privilege Escalation
Content
def _read_netrc(host: str) -> Optional[Tuple[str, ...]]:
    """从 ~/.netrc 读指定 host 的凭证(无 token 格式)。"""
    for path in (Path.home() / ".netrc", Path.home() / "_netrc"):
        if not path.is_file():
            continue
Confidence
96% confidence
Finding
~/.netrc

Credential Access

High
Category
Privilege Escalation
Content
def _resolve_with_netrc(env_name: str, netrc_host: str, field_index: int) -> str:
    """env > 用户 secrets > .netrc > 默认."""
    env_val = os.environ.get(env_name, "").strip()
    if env_val:
        return env_val
Confidence
93% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
_DEFAULTS: dict[str, str] = {
    "EARTHDATA_USERNAME": "ruiduobao",
    "EARTHDATA_PASSWORD": "Ruiduobao123",
    "EARTHDATA_TOKEN": "",  # 用户级 secrets.json 提供(不走默认值以免推到 GitHub)
    "FIRMS_MAP_KEY": "",
    "CMA_API_KEY": "",
    "OPENAI_API_KEY": "",
Confidence
100% confidence
Finding
secrets.json

Credential Access

High
Category
Privilege Escalation
Content
def load_user_secrets(path: Optional[Path] = None, *, force: bool = False) -> bool:
    """从 ``~/.geoskill/secrets.json`` 加载用户级凭证到 _DEFAULTS.

    Phase 7 (2026-07-27): 第一次调用自动加载(lazy)。之后每个 helper
    调用也会 lazy 加载,除非显式 ``force=True`` 强制重读。返回 True
Confidence
95% confidence
Finding
secrets.json

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
scipy
Confidence
96% confidence
Finding
numpy

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
scipy
Confidence
96% confidence
Finding
rasterio

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
scipy
Confidence
96% confidence
Finding
scipy

Known Vulnerable Dependency: numpy — 10 advisory(ies): CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +7 more

Critical
Category
Supply Chain
Confidence
89% confidence
Finding
numpy

Known Vulnerable Dependency: scipy — 4 advisory(ies): CVE-2013-4251 (SciPy creates insecure temporary directories); CVE-2013-4251 (The scipy.weave component in SciPy before 0.12.1 creates insecure temporary dire); CVE-2023-25399 (A refcounting issue which leads to potential memory leak was discovered in scipy) +1 more

High
Category
Supply Chain
Confidence
88% confidence
Finding
scipy

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/conftest.py:15