Back to skill

Security audit

geoskill-spectral-unmixing

Security checks across malware telemetry and agentic risk

Overview

The main tool appears to do local spectral unmixing, but the package also ships under-disclosed credential, download, and geocoding utilities that do not fit that purpose.

Review before installing. The documented command appears local, but the package includes extra shared geospatial utilities with credential discovery, hardcoded fallback credentials, external network calls, and user-home caching that are not disclosed in the skill instructions. Install only if you are comfortable with those bundled capabilities or after removing the unused credential/download/geocoding modules and rotating any exposed credentials.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (35)

Lp3

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding
The skill declares no permissions, yet its documented and detected capabilities include shell execution, file read/write, environment access, and network use. This creates a transparency and consent gap: operators may run the skill believing it is purely offline/local while it can access sensitive local data and external services.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The stated purpose is spectral unmixing, but the skill reportedly also includes geocoding/network resolution, generic download logic, credential discovery from environment/.netrc/secrets files, and broader utility components unrelated to the advertised function. This mismatch is dangerous because hidden credential access and network/download behavior materially expand the attack surface and could enable data exfiltration or unauthorized use of user secrets under the guise of a local geospatial workflow.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The vendored metadata claims the embedded core belongs to a different skill ('landsat-download') than the advertised spectral unmixing skill. This kind of provenance mismatch undermines trust, suggests copy/paste or packaging errors, and can conceal inclusion of capabilities or code paths that were not reviewed for the declared purpose.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The vendored file list includes download and credential-related modules even though the stated skill purpose is local spectral unmixing. Unjustified access to downloading or credential handling expands the attack surface and may enable unintended network access, secret use, or data exfiltration if those modules are invoked by hidden or future code paths.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
This module introduces broad credential-management capabilities for Earthdata, FIRMS, CMA, OpenAI, and EOG that are not justified by the stated purpose of a spectral unmixing skill. In a least-privilege skill context, collecting and resolving multiple third-party credentials materially expands the attack surface and enables abuse of unrelated accounts if any downstream code invokes these helpers.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The code reads sensitive data from environment variables, ~/.geoskill/secrets.json, and ~/.netrc for multiple services, creating a centralized credential harvesting surface. Even though this file itself does not transmit secrets, it normalizes access to user-stored credentials in a skill whose stated purpose does not clearly require them, increasing the risk of secret misuse by other components.

Intent-Code Divergence

Critical
Confidence
100% confidence
Finding
The documentation claims passwords are not hardcoded in skill source, yet the module embeds real-looking fallback Earthdata credentials in _DEFAULTS. Hardcoded credentials are a critical secret-management failure because they can be extracted from source control, reused unintentionally in production, and may expose a real external account if valid.

Description-Behavior Mismatch

High
Confidence
94% confidence
Finding
The file implements place-resolution and external geocoding logic that is unrelated to the declared purpose of a spectral unmixing skill. This capability expansion increases attack surface, can trigger unexpected outbound data flows, and suggests the skill may perform undisclosed functions beyond user expectations.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The code makes outbound requests to Open-Meteo and Nominatim even though such network access is not justified by the stated spectral unmixing functionality. In practice this can leak user-supplied place names and metadata to third parties, violate least-privilege expectations, and enable covert or unnecessary data exfiltration paths within an apparently offline analytical skill.

Missing User Warnings

High
Confidence
100% confidence
Finding
The fallback credentials include a plausible username and password and are silently used when other sources are absent. This can cause unauthorized account use, accidental credential leakage to users and logs, and creates a reusable secret embedded directly in distributed code.

Natural-Language Policy Violations

Medium
Confidence
76% confidence
Finding
The request hard-codes an Accept-Language preference of zh-CN/zh without user opt-in or justification. While not a code-execution issue, it can override user expectations, create privacy and profiling signals about locale, and produce biased or jurisdiction-specific results that are disconnected from the declared skill purpose.

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
92% 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
92% 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
92% 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
90% 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
93% 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
93% 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
93% 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
95% 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
95% 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
90% 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
解析顺序:
    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
91% 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
88% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
source 字段:
    - ``"env"``         — 来自环境变量
    - ``"user_secrets"`` — 来自 ~/.geoskill/secrets.json
    - ``"netrc"``        — 来自 ~/.netrc
    - ``"default"``      — 来自 _DEFAULTS(geoskill-core 硬编码兜底)
    - ``"none"``         — 全部未配
    """
Confidence
86% 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