Back to skill

Security audit

Geoskill: Satellite Search

Security checks across malware telemetry and agentic risk

Overview

The skill mostly matches its satellite-search purpose, but it bundles under-disclosed credential-handling code and risky dependency declarations that deserve review before installation.

Install only if you are comfortable with a network-capable satellite lookup tool that can scrape public sites, send missed queries to search engines, and optionally send eoPortal text to an LLM provider. Before using it, remove or review the bundled credential module, avoid running pip install -r requirements.txt without fixing the bare dependency names, and set SATELLITE_SEARCH_NO_ONLINE=1 or SATELLITE_SEARCH_NO_LLM=1 if those outbound behaviors are not acceptable.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The skill is marketed as 'offline-first' local search, but the documentation also describes live scraping, browser-fingerprinting evasion, web-search fallback, external LLM submission, and additional functionality beyond simple lookup. This mismatch can mislead operators into granting trust or running the skill in restricted environments without realizing it may transmit user queries and collected data to third parties or invoke broader code paths than expected.

Unvalidated Output Injection

High
Category
Output Handling
Content
tmp_path = tmp.name
    try:
        cmd = [exe, "search", q, "-n", str(min(num, 20)), "-o", tmp_path]
        cp = subprocess.run(cmd, capture_output=True, text=True, timeout=180)
    except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e:
        return None
    if cp.returncode != 0:
Confidence
67% confidence
Finding
subprocess.run(cmd, capture_output

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

Unpinned Dependencies

Low
Category
Supply Chain
Content
core
models
openai>=1.0.0
openpyxl>=3.0.0
Confidence
90% confidence
Finding
core

Unpinned Dependencies

Low
Category
Supply Chain
Content
core
models
openai>=1.0.0
openpyxl>=3.0.0
playwright>=1.30.0
Confidence
90% confidence
Finding
models

Unpinned Dependencies

Low
Category
Supply Chain
Content
openpyxl>=3.0.0
playwright>=1.30.0
requests>=2.28.0
scripts
translate_descriptions
Confidence
96% confidence
Finding
scripts

Unpinned Dependencies

Low
Category
Supply Chain
Content
playwright>=1.30.0
requests>=2.28.0
scripts
translate_descriptions
Confidence
96% confidence
Finding
translate_descriptions

Unpinned Dependencies

Low
Category
Supply Chain
Content
core
models
openai>=1.0.0
openpyxl>=3.0.0
playwright>=1.30.0
requests>=2.28.0
Confidence
85% confidence
Finding
openai>=1.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Content
core
models
openai>=1.0.0
openpyxl>=3.0.0
playwright>=1.30.0
requests>=2.28.0
scripts
Confidence
85% confidence
Finding
openpyxl>=3.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Content
models
openai>=1.0.0
openpyxl>=3.0.0
playwright>=1.30.0
requests>=2.28.0
scripts
translate_descriptions
Confidence
85% confidence
Finding
playwright>=1.30.0

Unpinned Dependencies

Low
Category
Supply Chain
Content
openai>=1.0.0
openpyxl>=3.0.0
playwright>=1.30.0
requests>=2.28.0
scripts
translate_descriptions
Confidence
88% confidence
Finding
requests>=2.28.0

Known Vulnerable Dependency: requests==2.28.0 — 8 advisory(ies): CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi); CVE-2026-25645 (Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility func) +5 more

High
Category
Supply Chain
Confidence
97% confidence
Finding
requests==2.28.0

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.