Back to skill

Security audit

geoskill-map-print-composition

Security checks across malware telemetry and agentic risk

Overview

The main map renderer is local, but the package also ships undisclosed credential, network, and home-directory cache helpers that do not fit the advertised offline map-printing purpose.

Only install this after reviewing whether you are comfortable with extra bundled geospatial helper code that can access local credential stores and contact third-party geocoding services. The main map-printing command appears local, but the package should remove or clearly separate the unused credential, downloader, and online geocoding modules before it is treated as a simple offline rendering skill.

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 Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (40)

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill metadata declares an offline/local map composition tool, yet the analyzer detected capabilities including shell, file read/write, environment access, and network without any declared permissions. Even if some capabilities are expected for geospatial processing, the undeclared access weakens user consent and reviewability, and could enable silent file access, environment secret exposure, or outbound connections inconsistent with the documented behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
This is a strong description-behavior mismatch: the skill presents itself as a local print-composition utility, but the detected behavior includes geocoding, remote network access, credential handling for multiple external services, downloading remote data, and broader remote-sensing helper functionality. Hidden expansion of scope is dangerous because users may run the skill expecting offline local processing while it can reach external services, consume secrets from the environment, and process or exfiltrate data beyond the advertised purpose.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The vendored metadata claims the embedded core belongs to a different skill ('landsat-download') than the current map-print composition skill. This indicates provenance or packaging inconsistency that can break trust in what code was bundled, causing reviewers and automated tooling to validate the wrong component and potentially miss malicious or unintended functionality. In a skill supply-chain context, mismatched identity metadata is especially risky because it undermines integrity checks and dependency auditing.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The file performs network geocoding against Open-Meteo and Nominatim, which expands the skill's behavior beyond the stated map-composition/rendering scope. This can transmit user-supplied place names to third-party services and introduces undeclared data-flow and dependency risk; in a security review, hidden external communication is a real issue even if the code is not overtly malicious.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The code persistently caches AOI query results under the user's home directory, which is stateful behavior not reflected in the skill description. Storing location-related lookups on disk can leak sensitive geographic intent, surprise users, and create residual data exposure on shared systems or in backups.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
This module is a broad credential broker for multiple external services and is materially unrelated to a skill described as map print composition. In a skill context, adding code that reads environment variables, ~/.netrc, and ~/.geoskill/secrets.json expands the attack surface and enables unauthorized access to sensitive credentials if the skill or downstream code is abused.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
Support for OPENAI_API_KEY is not justified by the stated purpose of composing printable maps. Unnecessary access to unrelated API credentials is dangerous because any later code path, plugin, or prompt-injection-driven behavior could leverage that credential to make external calls or exfiltrate data under the user's account.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The module advertises and implements access paths for multiple remote providers beyond what is needed for a print-composition-only skill. That mismatch increases suspicion and broadens credential exposure, because the skill can enumerate and retrieve secrets for external systems unrelated to its declared purpose.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Geocoding queries are sent to third-party services without any visible disclosure in this file, so user-entered locations may be exposed externally without informed consent. Even ordinary place names can reveal sensitive plans, interests, or operational context, making undisclosed transmission a privacy/security concern.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill writes place-query cache data into the user's home directory without visible disclosure, creating persistent local storage of location-related information. This can expose private user intent to other local users, incident responders, or backup/archive systems long after the original action.

Missing User Warnings

High
Confidence
99% confidence
Finding
The code contains hardcoded fallback credentials, including a plaintext username and password. Hardcoded secrets are dangerous because anyone with source access can recover and reuse them, and the skill will silently authenticate with those credentials when environment or user-provided secrets are absent.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
User-supplied place queries are sent to third-party geocoding services, which can expose potentially sensitive location intent, project names, or investigation targets to external providers without any disclosure in this file. In a map-print composition skill, this is more concerning because users may assume local rendering behavior while their AOI queries are transmitted off-box.

Natural-Language Policy Violations

Medium
Confidence
85% confidence
Finding
The code unconditionally sets Accept-Language to Chinese for Nominatim requests, overriding user or system locale without consent. This can leak assumptions about the operator's region, affect returned results, and create unnecessary privacy and correctness issues, especially in a general map-composition context where locale should be user-controlled.

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
88% 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
88% 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
88% 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
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
90% 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
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
        try:
Confidence
95% 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

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
87% 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