Back to skill

Security audit

geoskill-cloud-shadow-detection

Security checks across malware telemetry and agentic risk

Overview

The main tool appears to do local cloud-shadow detection, but the package also contains under-disclosed network and credential-handling code, including a hardcoded password.

Review before installing. Use only in an isolated environment without sensitive ~/.netrc, ~/.geoskill/secrets.json, or unrelated API keys present, and prefer a version that removes the hardcoded Earthdata password plus the unused credential, geocoding, and downloader modules or clearly gates and documents them.

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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill documentation declares no permissions, yet the referenced implementation is reported to have shell, network, environment, and file read/write capabilities. That mismatch can mislead users and reviewers about the true trust boundary, causing them to run a skill with broader access than expected.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared purpose is cloud/cloud-shadow detection, but the analyzed behavior includes geocoding, remote HTTP downloads, credential handling from env/.netrc/secrets, caching, and even hardcoded Earthdata fallback credentials. This is dangerous because it expands the attack surface far beyond the stated function and introduces risks of credential exposure, unintended network exfiltration, and unauthorized remote access.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The vendored metadata declares the skill as 'landsat-download' while the package is presented as a cloud-shadow-detection skill, indicating a supply-chain integrity or packaging mismatch. This can cause reviewers or automation to trust, validate, or import the wrong vendored components, increasing the risk of unintended code inclusion or weakened provenance checks.

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
The module sends user-supplied place names to third-party geocoding services over the network, which creates an external data disclosure channel not obvious from a nominally geospatial processing skill. In this skill context, AOI resolution can be legitimate, but doing it silently increases privacy and supply-chain risk because sensitive locations may be exposed to external providers.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
This credential helper is much broader than the stated cloud/cloud-shadow detection purpose and includes access paths for multiple unrelated secret types, including OPENAI and other external services. Expanding secret-handling scope increases attack surface and the chance that a narrowly scoped skill can access credentials not required for its function.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The code explicitly loads secrets from environment variables and user home files (~/.geoskill/secrets.json and ~/.netrc/_netrc), giving the skill a direct path to harvest locally available credentials. In the context of a cloud-shadow detection skill, that secret discovery capability is unnecessary and materially increases the risk of credential exposure if any downstream code misuses these helpers.

Intent-Code Divergence

Medium
Confidence
83% confidence
Finding
The documentation claims passwords are not cached, but load_user_secrets writes secret values into the module-global _DEFAULTS map and keeps them resident in process memory. This discrepancy can mislead reviewers and operators about exposure duration and complicates incident response and memory-scraping risk assessments.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The file implements place-name geocoding and outbound network resolution, which is materially unrelated to the stated purpose of cloud/cloud-shadow detection. In a skill whose advertised function is remote-sensing analysis, this hidden or unjustified capability expands attack surface and can exfiltrate user-supplied location queries to third parties, making the mismatch security-relevant rather than merely architectural drift.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The code sends user-controlled place queries to external geocoding services (Open-Meteo and Nominatim) over HTTP requests without any demonstrated necessity tied to the declared cloud-shadow detection behavior. This creates a data exposure channel to third parties and introduces dependency on remote services that can observe, log, or influence processing of sensitive location inputs.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The top-level docstring presents the file as a simple delegation shim, but the module still contains and executes substantial legacy network geocoding logic when the core import or call fails. That discrepancy is dangerous because reviewers or operators may believe the file is low-risk glue code while it actually retains independent outbound behavior and fallback execution paths.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The README’s activation and usage guidance is incomplete and still contains placeholder text, so users and orchestrating agents do not get clear constraints on when the skill should or should not be invoked. In an agent setting, ambiguous invocation criteria can cause misuse on unsupported inputs, unintended execution paths, or over-trust in the skill’s documented behavior, especially because the document also makes strong claims such as offline/local processing without enough supporting detail.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
User-entered place queries are transmitted to external geocoding endpoints without any disclosure in this file, which can leak sensitive operational or personal location intent. In a cloud-shadow detection workflow, AOI names may reveal projects, facilities, or areas of interest, so silent transmission meaningfully raises privacy risk.

Missing User Warnings

Low
Confidence
78% confidence
Finding
The code persists resolved AOI manifests to a file in the user's home directory without disclosure, creating local retention of potentially sensitive location history. While the risk is local and lower than network disclosure, cached place queries and bounding boxes may still expose private operational interests to other local users, backups, or forensic review.

Missing User Warnings

High
Confidence
99% confidence
Finding
The module contains hardcoded fallback credentials, including a plaintext EARTHDATA username and password. Hardcoded secrets are highly likely to leak through source control, package distribution, logs, or reuse across deployments, and they create unauthorized access risk even if intended as a fallback.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The requests transmit user-supplied place names to external providers without any in-file disclosure, consent flow, or indication that location data leaves the local environment. For location-related inputs, this is a meaningful privacy issue because place names may reveal sensitive operational, personal, or proprietary interests even if no account identifiers are sent.

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
89% 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
89% 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
89% 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
86% 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
87% 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
87% 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
87% 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
84% 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