Back to skill

Security audit

geoskill-earthquake-liquefaction-risk

Security checks across malware telemetry and agentic risk

Overview

The main liquefaction tool appears local and coherent, but the package also ships unrelated credential and network helper code that is not disclosed by the skill instructions.

Review this package before installing. The documented command-line tool appears to run local liquefaction calculations, but the shipped artifact contains broader reusable geospatial code that can access networks and local credential stores if used. Install only in an environment where you are comfortable with that bundled code, and remove or audit the credential helpers and hardcoded Earthdata credentials before use.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (16)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares no permissions, yet the artifact is assessed as having file, shell, environment, and network capabilities. That mismatch is dangerous because consumers may trust the markdown-declared offline/local behavior while the actual skill implementation can access sensitive local data or external services without explicit disclosure. In this context, the privacy section specifically claims local/offline processing, so undisclosed capabilities materially increase risk and reduce informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This is a strong description-behavior mismatch: the skill is presented as a local liquefaction calculator, but the analysis indicates unrelated geocoding, generic downloading, multiple external-service credential handling, and even hardcoded default credentials. Such hidden functionality can enable covert data exfiltration, unauthorized network access, misuse of embedded secrets, and supply-chain style abuse under the cover of a benign geoscience workflow. The mismatch is especially dangerous because the skill explicitly claims offline/local privacy guarantees, which would mislead users into granting trust they otherwise would not.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The vendored metadata claims the embedded core belongs to a different skill ('landsat-download') than the declared liquefaction-risk skill. This creates a software supply-chain integrity problem: reviewers and automated tooling may validate or trust the wrong component set, making it easier for mismatched, stale, or unintended code to be shipped without detection.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
This credential manager handles an OPENAI_API_KEY even though the stated skill is for liquefaction-risk evaluation, which increases the skill’s privilege surface beyond its declared purpose. Unnecessary credential pathways are dangerous because they allow future code in the same skill to access unrelated external services, violating least privilege and enabling covert data exfiltration or unreviewed API use.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The module is designed to broker credentials for multiple unrelated services beyond what is needed for a liquefaction-risk calculation. In a skill context, broad multi-service credential access is risky because any later-added code path can reuse this central helper to reach external systems that were not expected by the operator.

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
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
        try:
Confidence
86% 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
89% 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
91% 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
99% 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
87% confidence
Finding
secrets.json

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
scipy
Confidence
93% confidence
Finding
numpy

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
scipy
Confidence
93% confidence
Finding
rasterio

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
scipy
Confidence
94% confidence
Finding
scipy

Known Vulnerable Dependency: numpy — 10 advisory(ies): CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +7 more

Critical
Category
Supply Chain
Confidence
78% confidence
Finding
numpy

Known Vulnerable Dependency: scipy — 4 advisory(ies): CVE-2013-4251 (SciPy creates insecure temporary directories); CVE-2013-4251 (The scipy.weave component in SciPy before 0.12.1 creates insecure temporary dire); CVE-2023-25399 (A refcounting issue which leads to potential memory leak was discovered in scipy) +1 more

High
Category
Supply Chain
Confidence
84% confidence
Finding
scipy

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