Back to skill

Security audit

geoskill-flood-inundation-modeling

Security checks across malware telemetry and agentic risk

Overview

The main flood-modeling tool appears local, but the package also includes undisclosed credential, network, cache, and vendored-code provenance issues that users should review before installing.

Install only if you are comfortable with reviewing or removing the unused bundled core modules first. The normal flood CLI appears to process local DEM/synthetic data and write local outputs, but the package includes hidden network and credential-access capabilities that are not necessary for the stated offline workflow.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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 Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding
This skill is documented as fully offline DEM-based flood modeling, yet the analysis indicates additional hidden behaviors including geocoding, network access, download helpers, credential management, and embedded fallback credentials. That mismatch is dangerous because reviewers and users may trust the skill with sensitive local geospatial data under the assumption it never connects externally, while hidden network and credential logic could enable data exfiltration, unauthorized access, or misuse of embedded secrets.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The vendored core metadata claims the bundled code is for a different skill ('landsat-download') than the actual flood inundation skill. This kind of provenance mismatch undermines supply-chain integrity, makes it harder to verify that the correct dependency set was included, and can conceal accidental or unauthorized code substitution. In a geospatial skill that may process external data and credentials, incorrect vendoring metadata increases the risk of reviewers trusting the wrong package contents.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
This module is clearly out of scope for a static flood inundation modeling skill: it centralizes access to multiple unrelated third-party credentials, including OpenAI, CMA, FIRMS, and EOG. Expanding a narrowly scoped geospatial modeling skill into a general credential broker increases attack surface and enables unnecessary secret access if any downstream code imports these helpers.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The code reads secrets from user-home locations such as ~/.geoskill/secrets.json and ~/.netrc, which grants the skill implicit access to credentials outside its stated purpose. For an offline DEM bathtub modeling skill, this capability is unjustified and dangerous because any code path importing this module can harvest local secrets without clear user consent.

Context-Inappropriate Capability

Medium
Confidence
80% confidence
Finding
The code performs external network requests to Open-Meteo and optionally Nominatim using user-supplied place strings, which creates an outbound data flow not reflected in the manifest’s narrowly stated inundation-modeling purpose. In a restricted or privacy-sensitive environment, this can leak user-provided locations/queries to third parties and unexpectedly expand the skill’s trust boundary.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Place queries are sent to external geocoding services automatically, which can disclose sensitive or proprietary locations without user awareness. In a geospatial flood-modeling context, AOIs may correspond to critical infrastructure, disaster-response areas, or private assets, so silent transmission to third parties creates a real privacy and data-governance risk.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Resolved place queries are persisted under the user's home directory, which can leave a recoverable record of sensitive AOI lookups on shared systems or managed workstations. Because geographic targets in this skill may reveal operational planning or asset locations, undisclosed persistent caching increases privacy exposure and forensic leakage risk.

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
97% 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
97% 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
97% 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
96% 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
96% 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
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
Confidence
99% 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
99% 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
96% 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
97% 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
100% confidence
Finding
secrets.json

Credential Access

High
Category
Privilege Escalation
Content
# 用户级 secrets 文件位置(在用户 home,**不** vendor 到 skill 内部)。
# Phase 7 (2026-07-27): 包含 NASA Earthdata bearer token 等真实凭证。
USER_SECRETS_PATH = Path.home() / ".geoskill" / "secrets.json"

# 是否已加载过用户级 secrets(避免每次调用都重读)
_user_secrets_loaded = False
Confidence
97% 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
98% 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
88% confidence
Finding
numpy

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