Back to skill

Security audit

Geoskill: Sentinel Downloader Skill

Security checks across malware telemetry and agentic risk

Overview

The Sentinel downloader mostly matches its stated purpose, but it ships hidden, overbroad credential-handling code including hardcoded Earthdata login fallback credentials.

Review before installing. The main downloader appears to perform ordinary STAC searches and optional downloads, but the package should remove the hardcoded Earthdata fallback credentials, rotate that exposed account, and strip or clearly document unrelated credential helpers. Use a virtual environment and avoid --check-deps on shared or production systems unless you intend to let it install Python packages.

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 Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Lp3

Medium
Category
MCP Least Privilege
Confidence
75% confidence
Finding
The skill documentation advertises network access, shell execution, and local file read/write behavior, but no permissions are declared. This creates a transparency and consent problem: users and policy engines cannot accurately assess what the skill is allowed to do before use, increasing the chance of unintended file creation, shell execution, or network egress.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The described purpose is narrowly scoped to Sentinel imagery download, but the associated behavior reportedly includes unrelated geocoding, broad dataset support, credential handling for multiple external services, and even embedded fallback credentials. That mismatch is dangerous because it hides a much larger attack surface than users expect, and hardcoded credentials or unnecessary credential plumbing can enable unauthorized access or secret exposure.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
This credentials module is far broader than the declared Sentinel imagery downloader purpose and centralizes access to multiple unrelated services. In a skill context, that increases privilege and data-access scope unnecessarily, making credential harvesting or misuse easier if any part of the skill is compromised or behaves unexpectedly.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
Providing OpenAI API key retrieval in a Sentinel downloader is unrelated to the advertised functionality and expands the blast radius if the skill is abused. An attacker controlling or extending downstream code could exfiltrate or misuse the OpenAI key without any user expectation that this downloader should access it.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
Support for FIRMS, CMA, and EOG credentials is outside the narrow Sentinel downloader purpose and unnecessarily broadens accessible secrets. While not inherently malicious, this violates least privilege and increases the chance of cross-service credential exposure or misuse within the skill runtime.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The wrapper is presented as a Sentinel imagery downloader, but it also installs Python packages on the host when dependencies are missing. That behavior changes the user's environment and executes network-fetched code via pip, which expands the skill's privileges and attack surface beyond simple downloading.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Running pip from the skill gives it package installation capability that is not strictly necessary for a downloader wrapper at execution time. If a package source is compromised, dependency names are typosquatted, or pip configuration is hostile, the script can trigger arbitrary code execution and persistent host modification.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The module performs outbound geocoding requests and persists query-derived results under the user's home directory without any explicit disclosure or consent flow. In this skill context, place names can reveal sensitive user intent or locations, so silent network transmission and local persistence create a privacy and data-handling risk, especially on shared systems or in regulated environments.

Natural-Language Policy Violations

Medium
Confidence
73% confidence
Finding
The code hard-codes Accept-Language to zh-CN for Nominatim requests, overriding user preference and potentially disclosing language/region assumptions to a third-party service. This is primarily a privacy and policy issue rather than a direct code-execution risk, but it can affect user anonymity and produce jurisdiction-specific metadata exposure in a geospatial skill handling location lookups.

Missing User Warnings

High
Confidence
100% confidence
Finding
The code contains hardcoded fallback Earthdata credentials, including a plaintext password. Hardcoded secrets in source are highly dangerous because anyone with code access can immediately reuse them, and the skill may silently authenticate with embedded credentials without user awareness.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script installs packages as a side effect after only printing 'installing' messages, without a strong warning that it will modify the host environment. Users invoking a downloader may not expect software installation, creating consent and supply-chain risk, especially on shared or production systems.

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
86% 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
82% confidence
Finding
~/.netrc

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
requests>=2.28.0
Confidence
95% confidence
Finding
requests>=2.28.0

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:20