Back to skill

Security audit

geoskill-radiometric-calibration

Security checks across malware telemetry and agentic risk

Overview

The advertised calibration tool is mostly local, but the package includes undisclosed credential, geocoding, download, and persistent-cache helpers that exceed the stated purpose.

Review this skill before installing, especially on systems with ~/.netrc or ~/.geoskill/secrets.json. The safer package shape would remove unused credential/geocoding/download helpers, remove hardcoded fallback credentials, correct vendored metadata, pin dependencies, and clearly document any network or credential behavior that remains.

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

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill declares no permissions, yet the documented and detected capabilities include shell, network, environment access, and file read/write. This creates a transparency and least-privilege problem: users and orchestration systems may trust the skill as local-only while it can access sensitive resources or external services. In this context, the mismatch is more dangerous because the privacy section explicitly claims offline/local processing, which can mislead users about actual exposure.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The declared purpose is narrow radiometric calibration, but the finding indicates broader functionality including online geocoding, remote downloads, credential handling for multiple external services, and generic remote-sensing registry features. Such hidden or undocumented behavior significantly expands the attack surface, can expose secrets, and defeats user expectations about what the skill will do. Because the skill is presented as offline/local and focused on calibration, this mismatch makes the issue more dangerous, not less.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The vendored metadata claims the embedded core belongs to a different skill ('landsat-download') than the current radiometric-calibration skill. This creates a supply-chain integrity problem: reviewers and tooling may validate or reason about the wrong component, allowing mismatched code, stale dependencies, or unintended capabilities to be shipped under misleading metadata.

Context-Inappropriate Capability

High
Confidence
82% confidence
Finding
The code sends user-supplied place queries to external geocoding services (Open-Meteo and optionally Nominatim) despite the skill being described as radiometric calibration. In this context, unexpected network exfiltration of user inputs and dependency on third-party services expands the attack surface and can leak sensitive operational locations without clear necessity.

Context-Inappropriate Capability

Medium
Confidence
76% confidence
Finding
Persistent caching stores resolved AOI queries and derived location data under the user's home directory without any disclosure or retention control in this file. Even if intended for convenience, writing location-related data to disk can create a privacy and forensic exposure, especially when the skill's declared purpose does not suggest persistent geolocation handling.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
This module is far broader than the stated radiometric-calibration purpose and centralizes access to multiple unrelated third-party credentials. In a calibration-focused skill, adding generic credential brokerage materially increases the attack surface and creates an easy path for other code in the skill stack to access sensitive secrets unrelated to the declared function.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
Handling OPENAI_API_KEY in a skill whose declared purpose is DN-to-radiance/TOA calibration is unjustified and creates secret access unrelated to user expectations. Even without direct exfiltration in this file, exposing retrieval helpers for unrelated API keys increases the risk that downstream code can silently repurpose the runtime's credentials.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The module advertises support for multiple unrelated remote-service credentials despite the skill being presented as calibration-only. This scope mismatch is dangerous because users and reviewers may grant trust appropriate for an offline geospatial transform while the codebase can access broader online accounts and tokens.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
This file implements place-name geocoding, network lookups, and CLI behavior that are unrelated to the stated radiometric-calibration purpose. In an agent skill, capability drift like this is dangerous because it expands the attack surface, can exfiltrate user-supplied place data to third parties, and may let a seemingly harmless calibration skill perform unexpected external actions.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The code sends user-provided place queries to Open-Meteo and Nominatim, creating outbound data flows that are unjustified for a radiometric-calibration skill. Hidden or unnecessary external requests are risky because they leak input data, introduce supply-chain and availability dependencies, and violate user expectations about what the skill does.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
User-entered place names are transmitted to third-party geocoding endpoints with no user-facing warning in this file. That is a real privacy/security issue because place strings may reveal sensitive sites, projects, or movements, and the behavior is especially unexpected in a calibration-focused skill.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The code writes AOI manifests to a persistent cache in the user's home directory without user disclosure. Cached geolocation data can be recovered later by other local users, processes, backups, or forensic review, creating avoidable privacy exposure.

Missing User Warnings

High
Confidence
100% confidence
Finding
The source contains hardcoded fallback credentials, including a plaintext Earthdata username and password. Hardcoded credentials are immediately reusable by anyone with source access, can be abused outside the intended environment, and violate the module's own stated principle against embedding secrets in code.

Natural-Language Policy Violations

Medium
Confidence
79% confidence
Finding
Forcing `Accept-Language: zh-CN,zh;q=0.9` without user choice can disclose or impose locale preferences that the user did not request. While not as severe as the unjustified network access itself, it increases privacy risk, may bias results unexpectedly, and is especially suspicious given the skill’s unrelated radiometric-calibration purpose.

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
85% 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
85% 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
85% 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
82% 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
84% 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
84% 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
83% 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

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

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