Back to skill

Security audit

geoskill-geographically-weighted-regression

Security checks across malware telemetry and agentic risk

Overview

The advertised GWR command appears local, but the package also includes undeclared credential, geocoding, download, and remote-sensing helper code that does not fit the stated offline purpose.

Review this package before installing. The advertised regression script is narrow and local, but the bundled helper modules can access local credential stores, use embedded service credentials, make outbound geocoding/download requests, and write caches. Install only if you trust the publisher and are comfortable with that extra code being present, or ask the publisher to remove or isolate the unrelated vendored core and disclose any network or credential behavior.

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

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill declares itself as fully offline with no network requests, yet the detected capabilities include network, shell, environment access, and file read/write without any declared permissions or disclosure. This creates a trust and containment problem: users and hosting platforms cannot accurately assess or sandbox the skill, and hidden capability expansion can enable unexpected data access or command execution if the implementation matches the detected capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose is a local geospatial regression tool, but the static finding indicates substantially broader behavior including credential management for multiple external services, hardcoded fallback usernames/passwords, geocoding, HTTP downloading, and generic remote-sensing utilities. That mismatch is highly suspicious because unrelated secret handling and network-enabled data acquisition can be used to exfiltrate data, perform unauthorized access, or conceal a multi-purpose backdoor behind an innocuous analytics description.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The vendored metadata claims the embedded core belongs to a different skill ('landsat-download') than the advertised geographically weighted regression skill. This is a supply-chain integrity problem because provenance and review scope become ambiguous: operators may believe they are inspecting one capability while the package metadata points to another, which can hide mispackaging, accidental code reuse, or unauthorized component substitution.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
This file introduces network geocoding and persistent local caching behavior that is materially broader than the skill’s stated GWR-focused purpose. Hidden expansion of capability increases data exposure risk because user-supplied place names may be transmitted externally and stored on disk without being clearly represented in the skill description or consent flow.

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
The code sends place queries to external geocoding providers, adding outbound data transfer capability not implied by the declared regression-analysis function. Even if place names seem low sensitivity, they can reveal user interests, project locations, or regulated geographic targets when sent to third parties.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
This module is a broad credential broker for multiple external services and is materially unrelated to the declared GWR analytics purpose. More critically, it contains hardcoded fallback credentials for Earthdata, which turns the file from mere 'over-broad functionality' into an actual secret-handling vulnerability and an unnecessary expansion of the skill's privilege surface.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The code reads secrets from environment variables, ~/.geoskill/secrets.json, and ~/.netrc for several external services despite the skill being described as geographically weighted regression analytics. In this context, silent access to user credential stores is over-privileged behavior that could enable credential harvesting or misuse if the broader skill invokes these helpers.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
The module claims passwords are not cached and are read each call, but load_user_secrets() persists secrets into the module-global _DEFAULTS after first load. This increases secret lifetime in process memory and can mislead reviewers or operators about exposure characteristics, which is a genuine secret-handling weakness.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
This file implements a general-purpose remote downloader with retry, resume, and file-write capabilities that are not clearly required by the declared GWR analytics purpose. In an agent/skill environment, such off-scope network and filesystem primitives expand the attack surface by enabling retrieval of arbitrary remote content, potentially including untrusted code, oversized datasets, or policy-bypassing payloads if other parts of the skill invoke it unsafely.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The exposed safe_download/safe_download_many APIs permit arbitrary URL downloads to arbitrary local paths, which is broader than the regression-analysis use case and dangerous in a composable agent setting. Although the implementation includes some safety features, integrity checking is optional, there is no domain allowlist, and caller-controlled destination paths could be abused to place attacker-supplied files on disk for later misuse.

Description-Behavior Mismatch

High
Confidence
92% confidence
Finding
The legacy fallback performs outbound HTTP geocoding requests to third-party services, which expands the skill's behavior beyond the declared GWR analytics purpose and sends user-supplied location queries off-box. In a skill context, undeclared network-capable fallback logic is risky because it can leak sensitive inputs and bypass expectations that the tool is purely analytical/local.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
Geocoding requests are made to third-party services without any visible warning or consent mechanism in this file. That creates a privacy and compliance risk because user-entered locations may be disclosed externally without the user understanding that network transmission occurs.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Resolved place data is persisted under the user’s home directory by default, creating a local data retention risk without notice or consent. Cached AOI manifests can reveal past queries and geographic interests to other local users, backup systems, or forensic review.

Natural-Language Policy Violations

Medium
Confidence
72% confidence
Finding
Forcing the Nominatim Accept-Language header to Chinese without user choice can leak assumptions about the user or deployment and may affect returned content in a way the user did not request. This is primarily a privacy and transparency issue rather than a direct exploit path, but it is still unnecessary behavior that reduces user control.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code sends user-provided place names directly to Open-Meteo and Nominatim without any disclosure or consent mechanism in this file. Place queries can contain sensitive locations such as home addresses, facilities, or client sites, so transmitting them to third parties creates a privacy and data-governance risk.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
Forcing the 'Accept-Language: zh-CN,zh;q=0.9' header without user choice can disclose locale assumptions and affect how third-party services process or log the request. This is primarily a privacy/transparency issue rather than a direct compromise vector, but it is more concerning because it happens automatically during external requests.

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
97% 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
97% 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
90% 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
92% 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
95% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
解析顺序:
    1. env: EARTHDATA_TOKEN
    2. ~/.geoskill/secrets.json
    3. .netrc: machine urs.earthdata.nasa.gov account <TOKEN>
    4. _DEFAULTS(通常为空)
    """
    return _resolve("EARTHDATA_TOKEN")
Confidence
86% confidence
Finding
.netrc

Credential Access

High
Category
Privilege Escalation
Content
_DEFAULTS: dict[str, str] = {
    "EARTHDATA_USERNAME": "ruiduobao",
    "EARTHDATA_PASSWORD": "Ruiduobao123",
    "EARTHDATA_TOKEN": "",  # 用户级 secrets.json 提供(不走默认值以免推到 GitHub)
    "FIRMS_MAP_KEY": "",
    "CMA_API_KEY": "",
    "OPENAI_API_KEY": "",
Confidence
100% confidence
Finding
secrets.json

Credential Access

High
Category
Privilege Escalation
Content
# 用户级 secrets 文件位置(在用户 home,**不** vendor 到 skill 内部)。
# Phase 7 (2026-07-27): 包含 NASA Earthdata bearer token 等真实凭证。
USER_SECRETS_PATH = Path.home() / ".geoskill" / "secrets.json"

# 是否已加载过用户级 secrets(避免每次调用都重读)
_user_secrets_loaded = False
Confidence
91% confidence
Finding
secrets.json

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
95% confidence
Finding
secrets.json

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