Back to skill

Security audit

geoskill-text-to-map-nlp

Security checks across malware telemetry and agentic risk

Overview

This offline map-rendering skill includes under-disclosed network and credential helper code, so it should be reviewed before installation.

Review before installing. The documented command-line renderer appears local/offline, but the package includes extra helper modules for network geocoding, downloads, local credential discovery, and a hardcoded Earthdata credential fallback. Install only if you accept those bundled capabilities or after they are removed, disabled by default, and clearly documented.

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

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill metadata claims an offline mapping utility, yet the analyzed capability set includes environment access, file read/write, shell, and network behavior without any declared permissions. This creates an auditability and trust problem: operators may invoke the skill assuming it is local-only while it can access sensitive local data or communicate externally.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
This is a significant description-behavior mismatch: the skill is presented as an offline natural-language-to-map renderer, but the analyzed implementation reportedly includes credential harvesting paths (.netrc, env, secrets files), hardcoded NASA Earthdata credentials, generic HTTP download logic, and online geocoding. Hidden credential access and network retrieval materially expand the attack surface and can lead to secret exposure, unauthorized outbound requests, or misuse of embedded accounts.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The vendored metadata claims the embedded component belongs to the different skill 'landsat-download' while this package is presented as 'geoskill-text-to-map-nlp'. That mismatch undermines software provenance and makes it harder to verify that the bundled core matches the declared skill, which can hide accidental supply-chain mixups or intentional component substitution.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The file explicitly advertises 'offline first' behavior but performs live geocoding against Open-Meteo and Nominatim when a local match is not found. That can disclose user-supplied place queries and create unexpected network egress, which is a security/privacy issue when operators believe the skill is offline-only.

Intent-Code Divergence

Medium
Confidence
84% confidence
Finding
The documentation claims ambiguous results are returned as candidates instead of silently choosing the first, but resolve_place scores results and auto-selects a candidate. In a mapping skill, silently resolving an ambiguous location can misdirect downstream analysis or visualization and can hide data-quality or trust issues from the caller.

Description-Behavior Mismatch

High
Confidence
93% confidence
Finding
This module centralizes access to multiple third-party service credentials, including OpenAI and several remote geodata providers, despite the skill being described as an offline text-to-map renderer. That scope mismatch increases the attack surface and creates unnecessary pathways for secret access and later exfiltration if any other part of the skill invokes these helpers.

Context-Inappropriate Capability

High
Confidence
91% confidence
Finding
The code is explicitly designed to read OpenAI and several remote-service credentials even though the declared purpose is offline map generation. Unnecessary secret access violates least privilege and makes the skill more dangerous because it can harvest credentials unrelated to its stated task.

Intent-Code Divergence

Critical
Confidence
99% confidence
Finding
The documentation says passwords are not hardcoded in skill source, but the module contains a hardcoded Earthdata username and password fallback. Hardcoded credentials are highly sensitive: anyone with source access can recover them, and they may enable unauthorized service access or reveal real user or organizational accounts.

Description-Behavior Mismatch

High
Confidence
94% confidence
Finding
This file implements a general-purpose network downloader with arbitrary URL fetching, retries, resume support, and local file writing, which materially exceeds the stated skill scope of offline NLP parsing and map rendering. In a skill that is supposed to be offline, this creates an unnecessary capability for remote content retrieval and filesystem modification, increasing the attack surface for data exfiltration, unreviewed dependency/data fetches, and abuse of the host environment.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The presence of HTTP client functionality in a skill described as offline is a strong security concern because it enables outbound network access contrary to user and platform expectations. Even if intended for convenience, hidden or unjustified network capability can be used to fetch attacker-controlled content, contact external services, or bypass assumptions that the skill processes only local/offline data.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The code makes outbound requests to Open-Meteo geocoding and thereby transmits user-supplied place names to a third party, which contradicts the skill’s stated offline/local behavior. This creates a privacy and trust boundary issue because users and integrators may assume no network egress or external disclosure occurs.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The public resolve_place API defaults to delegating user input to an external resolver and falls back to another network-capable implementation, so online behavior is the normal path rather than an exceptional case. In a skill advertised as offline text-to-map processing, this is dangerous because it silently expands data exposure and operational capabilities beyond what consumers expect.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The module framing suggests a harmless compatibility shim, but the retained legacy fallback still performs network resolution. This mismatch is dangerous because reviewers or downstream users may rely on the description and miss that the code can still exfiltrate user queries externally.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The module sends user-provided place strings to external geocoding services with no disclosure or consent handling in this file. Even seemingly harmless location queries may contain sensitive operational, personal, or proprietary information, so transmitting them off-host creates a privacy and data-governance risk.

Missing User Warnings

High
Confidence
99% confidence
Finding
Sensitive credentials are embedded as fallback defaults at module scope, so they are silently used if higher-priority sources are absent. This can lead to undisclosed authentication attempts with exposed shared credentials and makes secret leakage trivial for anyone inspecting the codebase.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
User-provided place queries are sent directly to third-party geocoding services without an in-file warning, consent mechanism, or minimization controls. Even if the input seems low sensitivity, location queries can reveal personal intent, travel plans, or sensitive geographic interests when transmitted to external providers.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
Forcing the Accept-Language header to Chinese without user choice leaks a locale preference and can influence provider-side logging, content shaping, or jurisdictional routing. While lower severity than the outbound query itself, it still adds unnecessary metadata disclosure and can produce unexpected behavior for non-Chinese users.

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
82% 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
82% 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
80% 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
80% 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
78% 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
78% 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
78% 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
88% 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