Back to skill

Security audit

geoskill-viewshed-analysis

Security checks across malware telemetry and agentic risk

Overview

The main viewshed tool is local, but the package also includes under-disclosed network and credential helpers, including a hardcoded password.

Review this package before installing. Running the documented viewshed command appears local, but the package contains extra helper code that can access local credential files and make network requests if invoked. Do not install it in an environment with valuable ~/.netrc, ~/.geoskill/secrets.json, or service API keys unless the publisher removes or clearly documents those helpers and removes the hardcoded Earthdata password.

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 (19)

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The vendored metadata declares the embedded component as 'landsat-download' while the enclosing skill is 'geoskill-viewshed-analysis', which indicates a supply-chain integrity mismatch. Even though this file is only metadata, such inconsistencies can hide incorrect or substituted dependencies, mislead reviewers about what code is actually bundled, and weaken provenance verification for the skill.

Description-Behavior Mismatch

High
Confidence
89% confidence
Finding
This module introduces a broad credential broker for multiple unrelated external services inside a viewshed-analysis skill. Even without exfiltration code in this file, aggregating access to Earthdata, FIRMS, CMA, EOG, and OpenAI increases attack surface and enables later code in the skill to retrieve secrets unrelated to the stated purpose, which is suspicious in context.

Context-Inappropriate Capability

High
Confidence
92% confidence
Finding
Support for OPENAI_API_KEY is not justified by the declared purpose of DEM-based viewshed analysis. In this skill context, adding access to a valuable third-party API key is dangerous because any later prompt, plugin, or network path could misuse or exfiltrate that credential for unrelated consumption.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
Adding credential support for FIRMS, CMA, and EOG exceeds the apparent needs of a viewshed-analysis skill and creates unnecessary secret-access capability. In context, this mismatch makes the file more dangerous because the skill can read credentials for unrelated services from the user's environment and home directory.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The file implements a general-purpose network downloader with retry, resume, arbitrary URL input, and batch download support, which materially exceeds a viewshed-analysis skill’s stated local geospatial processing scope. In an agent setting, this expands the attack surface for SSRF, unapproved data exfiltration paths, and remote payload retrieval if upstream inputs are attacker-controlled.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
`safe_download` and `safe_download_many` accept arbitrary URLs and write the response to local files, with no host allowlist, scheme restriction, or validation that the download is relevant to the geospatial task. In a tool-enabled agent, this can be abused to fetch attacker-chosen content, probe internal services, or stage follow-on attacks through downloaded files.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
User-supplied place strings are sent to third-party geocoding services, which can leak sensitive locations, project names, or operational context without explicit user awareness. In this viewshed-analysis context, queried places may reveal intended surveillance, planning, or site-analysis targets, increasing privacy and operational sensitivity.

Natural-Language Policy Violations

Medium
Confidence
81% confidence
Finding
Forcing an Accept-Language header of zh-CN/zh without user choice can disclose locale assumptions and influence provider-side profiling or response shaping. While lower severity than raw query exfiltration, it unnecessarily adds metadata about the user/environment and may produce biased or unexpected results.

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 dangerous because they may be valid shared credentials, can be extracted by anyone with code access, and may silently authorize network operations under an unintended account without user awareness.

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
82% 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
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
        try:
Confidence
87% confidence
Finding
.netrc

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

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
84% 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
95% 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
89% confidence
Finding
numpy

Known Vulnerable Dependency: scipy — 4 advisory(ies): CVE-2013-4251 (SciPy creates insecure temporary directories); CVE-2013-4251 (The scipy.weave component in SciPy before 0.12.1 creates insecure temporary dire); CVE-2023-25399 (A refcounting issue which leads to potential memory leak was discovered in scipy) +1 more

High
Category
Supply Chain
Confidence
88% confidence
Finding
scipy

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