Back to skill

Security audit

geoskill-lidar-ground-classification

Security checks across malware telemetry and agentic risk

Overview

The documented LiDAR workflow is local, but the package includes under-disclosed helper code for network access and credential handling, including a plaintext fallback credential.

Review this before installing. Use only the documented LiDAR script path if you proceed, and do not grant this package credentials or reuse its bundled helper modules without removing or narrowing the network, cache, and credential code. The hardcoded fallback credential should be removed and rotated by the publisher.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This is a serious description-behavior mismatch: the skill claims to perform offline LiDAR classification, but the finding indicates additional functionality for online geocoding, HTTP downloads, credential management, and even hardcoded default Earthdata credentials. Hidden network access and embedded credentials materially expand the attack surface, can mislead users into exposing data or secrets, and may enable unauthorized external access contrary to the stated privacy model.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The vendored metadata declares the embedded component as 'landsat-download' even though this skill is presented as a LiDAR ground-classification skill. That mismatch is a real supply-chain/integrity concern because it suggests the packaged dependency may be reused from a different capability, mislabeled, or accidentally swapped, which can hide unexpected code paths or permissions from reviewers.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The module performs live external geocoding requests to Open-Meteo and Nominatim and can persist results locally, which expands the skill’s capabilities beyond stated LiDAR ground-classification behavior. In a local processing skill, unexpected outbound network access can leak user-supplied locations and create hidden data flows that users and operators would not expect.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
This file introduces context-inappropriate network geocoding capability into a skill described as LiDAR ground classification, creating an unnecessary outbound communication channel. That increases attack surface, enables unintended disclosure of queried places or AOIs to third parties, and violates least-privilege for an ostensibly local geospatial processing task.

Context-Inappropriate Capability

Low
Confidence
88% confidence
Finding
The code writes cache files under the user’s home directory, creating persistent local state unrelated to the core ground-classification function. While not directly code-execution, it can retain sensitive place queries and AOI metadata longer than expected and may violate environment or privacy expectations for ephemeral processing tools.

Context-Inappropriate Capability

High
Confidence
92% confidence
Finding
This module gives a LiDAR ground-classification skill broad credential-management capabilities unrelated to its stated purpose, including access paths for Earthdata, FIRMS, CMA, OpenAI, and EOG secrets. In this skill context, that scope expansion is dangerous because it allows the skill or any imported code to reach unrelated user secrets, increasing the blast radius of compromise and violating least privilege.

Context-Inappropriate Capability

Critical
Confidence
99% confidence
Finding
The file hardcodes fallback Earthdata credentials directly in source code, including a plaintext username and password. Hardcoded secrets are inherently dangerous because they can be extracted from the repository, reused by unintended parties, and silently used at runtime even when the operator did not intend to supply credentials.

Intent-Code Divergence

Medium
Confidence
84% confidence
Finding
The docstring states passwords are not cached, but `load_user_secrets()` copies loaded secrets into the module-level `_DEFAULTS` dictionary and tracks load state globally. This persistence means secrets remain in process memory longer than advertised, creating a security/design mismatch that can mislead reviewers and operators about exposure.

Description-Behavior Mismatch

Medium
Confidence
87% confidence
Finding
This file provides a generic network downloader with retry, resume, and arbitrary URL support that is broader than the stated LiDAR ground-classification purpose. In a skill context, such capability can enable unauthorized data exfiltration, retrieval of untrusted payloads, or expansion of the skill’s effective permissions beyond user expectations, especially if downstream code passes attacker-controlled URLs.

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
The `_http_get` helper performs generic remote URL fetching with caller-supplied URLs and headers, which is risky in a skill whose declared purpose is local LiDAR ground classification. This increases attack surface for SSRF-like misuse, downloading malicious content, or contacting unintended internal/external endpoints if untrusted input can influence the URL.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The skill exposes place-name resolution and AOI geocoding behavior that is not aligned with the stated LiDAR ground-classification purpose. This creates unnecessary external-data and network functionality, increasing the attack surface and enabling collection or transmission of user-supplied location data beyond what the manifest suggests.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The code makes external HTTP requests to Open-Meteo and Nominatim using user-provided place names, which is unrelated to the declared LiDAR classification function. In this context, undisclosed outbound requests can leak sensitive operational locations, violate least-privilege expectations, and introduce dependency on third-party services for a skill that should primarily perform local geospatial processing.

Credential Access

High
Category
Privilege Escalation
Content
/ `EARTHDATA_TOKEN` / `FIRMS_MAP_KEY` / `OPENAI_API_KEY` /
  `CMA_API_KEY` / `EOG_USERNAME` / `EOG_PASSWORD` 任何一项显式设置
  都优先于默认值。
- **支持 .netrc**:若 ~/.netrc 中存在 `machine urs.earthdata.nasa.gov`
  行,优先取 .netrc 凭证。
- **支持用户级 secrets 文件** ``~/.geoskill/secrets.json``:Phase 7
  (2026-07-27) 新增。本文件在用户 home,**不** vendor 到任何 skill,
Confidence
81% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
/ `EARTHDATA_TOKEN` / `FIRMS_MAP_KEY` / `OPENAI_API_KEY` /
  `CMA_API_KEY` / `EOG_USERNAME` / `EOG_PASSWORD` 任何一项显式设置
  都优先于默认值。
- **支持 .netrc**:若 ~/.netrc 中存在 `machine urs.earthdata.nasa.gov`
  行,优先取 .netrc 凭证。
- **支持用户级 secrets 文件** ``~/.geoskill/secrets.json``:Phase 7
  (2026-07-27) 新增。本文件在用户 home,**不** vendor 到任何 skill,
Confidence
81% confidence
Finding
~/.netrc

Credential Access

High
Category
Privilege Escalation
Content
`CMA_API_KEY` / `EOG_USERNAME` / `EOG_PASSWORD` 任何一项显式设置
  都优先于默认值。
- **支持 .netrc**:若 ~/.netrc 中存在 `machine urs.earthdata.nasa.gov`
  行,优先取 .netrc 凭证。
- **支持用户级 secrets 文件** ``~/.geoskill/secrets.json``:Phase 7
  (2026-07-27) 新增。本文件在用户 home,**不** vendor 到任何 skill,
  **不** push 到 GitHub;用于把个人真实凭证(NASA Earthdata bearer
Confidence
81% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
(2026-07-27) 新增。本文件在用户 home,**不** vendor 到任何 skill,
  **不** push 到 GitHub;用于把个人真实凭证(NASA Earthdata bearer
  token 等)放在 skill 之外。
- **不缓存密码**:每次调用读环境或 .netrc(避免长寿命进程泄露)。
- **统一接口**:`get_earthdata_creds()` / `get_earthdata_token()` /
  `get_firms_key()` / `get_cma_key()` / `get_openai_key()` /
  `get_eog_creds()` 六个 helper。
Confidence
78% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
"EOG_PASSWORD": "",
}

# .netrc 解析(仅在 UNIX-like / WSL 下 ~/.netrc 可用;Windows 下
# 通常用 %USERPROFILE%\_netrc,但 .netrc 本身仍是约定俗成的名称)。
_NETRC_HOSTS = {
    "urs.earthdata.nasa.gov": ("EARTHDATA_USERNAME", "EARTHDATA_PASSWORD"),
Confidence
83% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
"EOG_PASSWORD": "",
}

# .netrc 解析(仅在 UNIX-like / WSL 下 ~/.netrc 可用;Windows 下
# 通常用 %USERPROFILE%\_netrc,但 .netrc 本身仍是约定俗成的名称)。
_NETRC_HOSTS = {
    "urs.earthdata.nasa.gov": ("EARTHDATA_USERNAME", "EARTHDATA_PASSWORD"),
Confidence
83% confidence
Finding
~/.netrc

Credential Access

High
Category
Privilege Escalation
Content
}

# .netrc 解析(仅在 UNIX-like / WSL 下 ~/.netrc 可用;Windows 下
# 通常用 %USERPROFILE%\_netrc,但 .netrc 本身仍是约定俗成的名称)。
_NETRC_HOSTS = {
    "urs.earthdata.nasa.gov": ("EARTHDATA_USERNAME", "EARTHDATA_PASSWORD"),
    "firms.modaps.eosdis.nasa.gov": ("FIRMS_MAP_KEY",),
Confidence
83% confidence
Finding
.netrc

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
90% confidence
Finding
~/.netrc

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
        try:
Confidence
90% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
def _resolve(name: str) -> str:
    """env > 用户 secrets > .netrc > 默认. 空字符串视为未设."""
    env_val = os.environ.get(name, "").strip()
    if env_val:
        return env_val
Confidence
80% 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
86% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
解析顺序:
    1. env: EARTHDATA_USERNAME / EARTHDATA_PASSWORD
    2. ~/.geoskill/secrets.json
    3. .netrc: machine urs.earthdata.nasa.gov
    4. _DEFAULTS 兜底
    """
    u = _resolve_with_netrc("EARTHDATA_USERNAME", "urs.earthdata.nasa.gov", 0)
Confidence
84% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
解析顺序:
    1. env: EARTHDATA_TOKEN
    2. ~/.geoskill/secrets.json
    3. .netrc: machine urs.earthdata.nasa.gov account <TOKEN>
    4. _DEFAULTS(通常为空)
    """
    return _resolve("EARTHDATA_TOKEN")
Confidence
82% confidence
Finding
.netrc

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