Back to skill

Security audit

geoskill-lidar-terrain-modeling

Security checks across malware telemetry and agentic risk

Overview

The main LiDAR tool looks mostly local, but the package includes under-disclosed credential, network geocoding, download, and persistence helpers that do not fit the advertised offline terrain-modeling purpose.

Review this package carefully before installing. The visible LiDAR workflow is local, but the bundle contains credential and network helpers that are not needed for the documented examples; use it only in an environment where local credential files are isolated, or ask the publisher for a stripped package with hardcoded credentials removed and network/credential behavior clearly documented.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (39)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises shell execution, file read/write, environment access, and possible network use through installation and execution examples, but declares no permissions or capability boundaries. This creates a transparency and policy-enforcement gap: users and hosting platforms cannot accurately assess or constrain what the skill may do before running it.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The reported behavior extends well beyond LiDAR terrain modeling into network requests, downloading, credential handling, and even hardcoded default Earthdata credentials. That combination materially increases risk because hidden or unrelated functionality can exfiltrate data, fetch untrusted content, or misuse embedded credentials under the guise of a benign geospatial skill.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The vendored metadata claims the embedded core belongs to a different skill ('landsat-download') than the advertised LiDAR terrain-modeling skill. This indicates a supply-chain integrity or packaging mismatch: auditors and automation may trust the wrong provenance, and the skill may be built from unintended components or a tampered bundle.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The module sends user-supplied place names to third-party geocoding services and persists results in a home-directory cache, which expands the skill’s data-handling and filesystem capabilities beyond its stated LiDAR terrain-modeling purpose. Even if used for convenience, this can leak sensitive AOI queries and create persistent local artifacts without clear necessity or disclosure.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
Using external geocoding services introduces outbound network access that is not obviously required by the published terrain-modeling functionality. This creates an unnecessary data exfiltration path for user AOI inputs and adds dependency on third-party services that may log or profile requests.

Context-Inappropriate Capability

Low
Confidence
83% confidence
Finding
The code writes cache files under the user’s home directory, creating persistent state unrelated to the advertised modeling outputs. While not immediately severe, this can retain potentially sensitive location queries longer than users expect and can violate least-privilege expectations for a data-processing skill.

Description-Behavior Mismatch

High
Confidence
93% confidence
Finding
This LiDAR terrain-modeling skill contains a general-purpose credential-management module for multiple external services that are unrelated to DEM/slope/aspect generation. That scope expansion increases attack surface and enables the skill to discover or use credentials from the local environment without a clear functional need, which is especially concerning in an agent skill context.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The module can access credentials for OpenAI, CMA, FIRMS, Earthdata, and EOG despite the skill being described as local LiDAR terrain modeling. Unnecessary collection and resolution of unrelated credentials creates a privilege-escalation opportunity where a compromised or overly broad skill can later use secrets for services outside its stated purpose.

Intent-Code Divergence

Critical
Confidence
99% confidence
Finding
The documentation claims passwords are not hardcoded in source, but the module embeds a fallback Earthdata username and password in code. Hardcoded credentials are a direct secret exposure risk: anyone with source access can recover and reuse them, and they may also encourage insecure deployment patterns or unauthorized third-party access.

Intent-Code Divergence

Medium
Confidence
83% confidence
Finding
The comments state that passwords are not cached and are read fresh each call, but `load_user_secrets()` persists secret values into the module-level `_DEFAULTS` dictionary after first load. This mismatch can mislead reviewers and operators about secret lifetime in memory, increasing the chance of unsafe assumptions in long-lived processes and weakening the trustworthiness of the security design.

Context-Inappropriate Capability

High
Confidence
88% confidence
Finding
The code sends user-supplied place queries to external services (Open-Meteo and Nominatim), which creates an undeclared data egress path and exposes user inputs and metadata to third parties. In a LiDAR terrain-modeling skill, this is riskier because users may expect local raster/point-cloud processing, not network transmission of AOI-related inputs, so the behavior can violate privacy, compliance, or deployment assumptions.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The module transmits user-provided place queries to external services without any visible warning, consent step, or privacy disclosure. AOI names can be sensitive in geospatial workflows, so silent transmission to third parties creates a real privacy and compliance risk even if no other data is sent.

Missing User Warnings

High
Confidence
99% confidence
Finding
Fallback credentials are embedded directly in source without user disclosure, and one of them is a non-empty Earthdata password. This creates an immediate credential leak and may cause silent use of shared credentials, making abuse, account compromise, and attribution problems much more likely.

Missing User Warnings

Medium
Confidence
81% confidence
Finding
The code automatically reads `~/.geoskill/secrets.json` and imports secrets into process state without any runtime disclosure or explicit user action. In an agent skill, silent discovery of sensitive local credentials is dangerous because users may believe a terrain-processing skill is operating only on LiDAR data, not probing home-directory secret stores.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The module automatically parses `.netrc` and `_netrc` files to retrieve credentials with no user-facing disclosure. Accessing broadly used credential stores from a skill whose purpose is unrelated to remote account management increases the risk of covert credential harvesting or accidental overreach.

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
78% 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
78% 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
78% 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
74% 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
79% 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
79% 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
80% 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
76% 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