Back to skill

Security audit

geoskill-crs-transformation

Security checks across malware telemetry and agentic risk

Overview

The main CRS converter is local, but the package also bundles undisclosed network, download, and credential-handling code, including a plaintext fallback password.

Review before installing. The normal CRS command appears local, but the package should remove or clearly split the geocoding, downloader, and credential modules, delete and rotate the embedded Earthdata password, and document any network or credential behavior before use in an environment with private location queries or stored API credentials.

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 Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (44)

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The vendored metadata claims the embedded core came from the unrelated skill 'landsat-download' while this package is declared as a CRS transformation skill. That provenance mismatch breaks auditability and supply-chain trust: reviewers and tooling may validate the wrong source, miss unauthorized code reuse, or incorrectly assume the vendored files were copied from a different, trusted package.

Description-Behavior Mismatch

High
Confidence
93% confidence
Finding
This file materially expands the skill from CRS transformation into AOI place resolution, online geocoding, and manifest generation. In a security review, that scope expansion matters because it introduces new trust boundaries and data flows not implied by the advertised skill purpose, increasing the chance of unintended network access and persistent data handling.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The code sends user-supplied place names to external geocoding services (Open-Meteo and Nominatim). That creates an unnecessary exfiltration channel for user input in a skill whose stated purpose is coordinate reference system transformation, especially because users may not expect network activity from such a skill.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The module defines a persistent cache directory under the user's home directory for storing resolved location data. Persistent storage is not necessary for basic CRS transformation and can retain sensitive or business-relevant place queries beyond the current session without clear user expectation.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The docstring claims ellipsoid-corrected geodesic area computation, but the implementation uses a simple spherical formula with the WGS84 semi-major axis only. In geospatial workflows, this can silently produce materially inaccurate area values, which may lead downstream policy, billing, compliance, or safety decisions to rely on incorrect measurements; the risk is higher because the function is presented as a correctness-enforcing check module.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
This module materially expands a CRS-transformation skill into a multi-service credential broker, including access paths for Earthdata, FIRMS, CMA, EOG, and OpenAI secrets. In an agent-skill context, unnecessary secret-handling code increases the attack surface and enables unrelated data access if other parts of the skill or host agent invoke these helpers.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The file reads and normalizes secrets for unrelated network services, including OPENAI_API_KEY, despite the stated purpose being coordinate reference transformation. In a skill package, such unrelated secret access is dangerous because it creates hidden capability to harvest or misuse credentials beyond the user’s expected scope.

Intent-Code Divergence

Critical
Confidence
100% confidence
Finding
The docstring claims passwords are not hardcoded in skill source, but the module contains embedded fallback credentials including a plaintext username and password. Hardcoded credentials are a direct secret exposure: anyone with source access can reuse them, and downstream consumers may unknowingly authenticate with compromised shared credentials.

Description-Behavior Mismatch

High
Confidence
89% confidence
Finding
This file introduces a full-featured generic downloader with retry, resume, batch download, and arbitrary local file write capability, which is unrelated to the declared CRS transformation purpose. In a skill ecosystem, hidden or unnecessary network/file I/O materially expands the attack surface by enabling remote payload retrieval or unreviewed data ingress under the guise of a geospatial utility.

Context-Inappropriate Capability

High
Confidence
93% confidence
Finding
The code allows downloading arbitrary URLs with caller-controlled destinations and filenames, creating unrestricted network egress and local persistence capability inside a skill whose stated purpose does not justify it. Even without obvious exploitation in this file, such capability can be composed with other code paths to fetch malicious content, exfiltrate request metadata, or stage follow-on attacks.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
The public API exposes place-name resolution parameters and delegates to a resolver that performs online geocoding, which is outside the declared scope of a CRS transformation skill. This creates an undeclared network/data-flow capability: user-supplied place names can be transmitted to third-party services, increasing privacy, compliance, and supply-chain risk in environments that expect only offline coordinate math.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The module issues outbound HTTP requests to Open-Meteo and Nominatim using user-controlled queries, despite the skill being described only as coordinate reference system transformation. In a least-privilege agent environment, this hidden egress enables unintended data disclosure, policy bypass, and dependency on third-party services that may log queries or affect behavior via remote responses.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
User-provided location queries are transmitted to third-party services without any user-facing disclosure or consent mechanism in this code path. Even if the data seems low sensitivity, place names can reveal user interests, operations, or physical targets, making the undisclosed sharing a meaningful privacy and security concern.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The code writes resolved query data to a persistent cache file in the user's home directory without warning. This can leave a local history of searched places that may expose sensitive operational context to other local users, backups, or forensic review.

Missing User Warnings

High
Confidence
99% confidence
Finding
Hardcoded fallback credentials are used silently, without clear runtime disclosure, making it easy for deployments to authenticate using embedded shared secrets unintentionally. This is dangerous because users may believe no credentials are configured while the code still accesses external services with exposed defaults.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The resolver functions silently inspect environment variables, user secrets, and .netrc to obtain credentials without any explicit notice at the point of use. In an agent context, silent secret discovery is risky because it can surprise users and enable unintended authentication against external services.

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
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
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
86% 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
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
93% 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
93% 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