Back to skill

Security audit

geoskill-spatial-regression

Security checks across malware telemetry and agentic risk

Overview

The advertised offline spatial-regression skill ships extra network, download, and credential-handling code that is not disclosed to users.

Review this skill carefully before installing. The main regression script appears local, but the package also ships undisclosed helpers for network geocoding, file downloads, local credential discovery, home-directory caching, and hardcoded Earthdata fallback credentials. Install only if you are comfortable with those extra capabilities or after they are removed or clearly gated by explicit user action.

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 Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
A strong description-behavior mismatch is a security red flag because the skill presents itself as an offline spatial regression tool while static analysis indicates additional geocoding, remote HTTP access, downloading logic, credential handling, and even hardcoded default Earthdata credentials. This hidden expansion of scope can lead to unexpected data exfiltration, unauthorized external communication, and secret exposure, especially because the declared privacy statements explicitly deny network use.

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 skill ('geoskill-spatial-regression'), which is a supply-chain integrity problem. This mismatch can conceal copied or repurposed code, cause reviewers and tooling to trust the wrong component provenance, and increase the risk that unexpected functionality or unsafe dependencies are shipped unnoticed.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The module sends user-supplied place names to external geocoding services (Open-Meteo and optionally Nominatim), creating an unintended data exfiltration path for potentially sensitive location queries. In a skill described as spatial diagnostics/regression, this network behavior is not obvious from the skill context, so users may not expect their inputs to leave the local environment.

Context-Inappropriate Capability

Low
Confidence
88% confidence
Finding
The code persists geocoding inputs and derived AOI manifests under the user's home directory, which can retain sensitive place queries longer than expected. While not code execution or privilege escalation, it creates unnecessary local data retention unrelated to core regression functionality and can expose user activity to other local processes or users with filesystem access.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
This module implements broad credential discovery and access for multiple external services, which is materially unrelated to a spatial regression skill's stated purpose. In context, that scope expansion increases the attack surface and enables the skill to access sensitive local secrets and service accounts that users would not reasonably expect for geospatial regression workflows.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The code reads credentials from environment variables, ~/.netrc, and ~/.geoskill/secrets.json for several services, despite the skill being described as spatial regression. That mismatch makes the behavior more dangerous because the skill gains the capability to enumerate and consume local secrets unrelated to its advertised purpose, which is a classic over-privileged design issue.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The module sends user-supplied place strings to third-party geocoding services over the network, which creates a real data exposure surface not justified by the stated skill scope. In a spatial regression skill context, hidden or undocumented outbound requests can leak sensitive locations, internal project names, or analyst intent to external providers and may violate deployment assumptions in restricted environments.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
User-entered location strings are transmitted to third-party geocoding providers without any in-file notice, consent flow, or privacy disclosure. This is dangerous because place names can reveal sensitive operational, personal, or research locations, and the skill's stated purpose does not strongly imply external data sharing.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The module stores geocoding queries and results in a cache directory under the user's home folder without in-file disclosure, which can silently persist sensitive location history. Even if intended as a performance optimization, undisclosed retention of location-derived data increases privacy risk and may violate user expectations or data-handling requirements.

Natural-Language Policy Violations

Medium
Confidence
85% confidence
Finding
The Nominatim request hard-codes an Accept-Language header favoring Chinese, which leaks a locale preference to the third-party service and overrides user choice. This is primarily a privacy and transparency issue rather than a direct compromise, but it is unnecessary metadata disclosure without opt-in.

Missing User Warnings

High
Confidence
100% confidence
Finding
The module contains hardcoded fallback credentials for EARTHDATA_USERNAME and EARTHDATA_PASSWORD in source code. Hardcoded live credentials are highly dangerous because anyone with code access can reuse them, and any code path invoking these helpers may silently authenticate to an external account without user knowledge or consent.

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
90% 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
90% 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
90% 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
89% 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
89% 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
89% 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
96% 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
96% 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
87% 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
90% 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
90% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
都优先于默认值。
- **支持 .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
  token 等)放在 skill 之外。
Confidence
92% confidence
Finding
secrets.json

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
99% confidence
Finding
secrets.json

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