Back to skill

Security audit

geoskill-farmland-productivity

Security checks across malware telemetry and agentic risk

Overview

The main farmland analysis tool is local, but the package also includes under-disclosed credential, geocoding, download, and cache code that does not fit the advertised offline-only behavior.

Review this package before installing. The advertised CLI appears local, but the bundle contains under-disclosed network geocoding, disk caching, broad credential loading, and hardcoded service credentials. Install only in an isolated environment and avoid placing real credentials in ~/.geoskill/secrets.json or ~/.netrc for this skill unless the package is cleaned up and documented.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (17)

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill advertises local/offline geospatial processing, yet static analysis detected capabilities for environment access, file read/write, shell, and network without any declared permissions or transparent disclosure. This is dangerous because users and orchestrators cannot make informed trust decisions, and hidden capabilities increase the blast radius if the skill is misused or compromised.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
There is a strong description-behavior mismatch: the skill claims to estimate farmland productivity from NDVI, but analysis indicates geocoding, broad remote downloads, unrelated service integrations, centralized credential handling, and even hardcoded fallback credentials. In this context, that mismatch is especially dangerous because a narrowly scoped scientific skill should not need broad external access or embedded secrets; such hidden behavior can enable data exfiltration, unauthorized API use, or abuse of user trust.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The vendored metadata claims the embedded core belongs to a different skill ('landsat-download') than the declared farmland-productivity skill. This creates a supply-chain integrity gap: reviewers and tooling may trust or validate the wrong component lineage, allowing unintended or stale code to be shipped under misleading metadata. In a geospatial skill, that mismatch is especially concerning because vendored download/core modules can affect data access, provenance, and runtime behavior beyond the stated purpose.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The module sends user-supplied place queries to third-party geocoding services, which can expose potentially sensitive location information to external providers without any consent flow in this code path. In a geospatial skill, this is functional rather than overtly malicious, but it still creates a privacy and data-handling risk because inputs may reveal farms, facilities, or other sensitive AOIs.

Context-Inappropriate Capability

Low
Confidence
80% confidence
Finding
The code enables a default cache directory under the user's home directory and later stores query-derived AOI manifests there. This can leave sensitive location queries persisted on disk longer than expected, creating a local privacy exposure on shared systems or managed environments.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The function documentation states it applies a spherical approximation plus an ellipsoidal correction, but the implementation only uses a spherical area formula with radius WGS84_A. In a geospatial productivity skill, this can mislead downstream users into trusting area-derived results as more scientifically accurate than they are, causing systematic bias in biomass or productivity estimates over large or high-latitude regions.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The module-level policy says antimeridian-crossing bounding boxes must be rejected unless specially handled, but check_bbox_wgs84 only flags values outside [-180,180] and treats normal wraparound cases like W=170, E=-170 as a generic W<E failure rather than explicitly detecting antimeridian crossing. This can lead callers to mishandle valid dateline-crossing extents, producing incorrect area checks, clipping, or data selection in global geospatial workflows.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The README leaves key sections as placeholders and does not clearly specify invocation conditions, supported inputs, or operational boundaries. Ambiguous trigger scope can cause an agent or user to invoke the skill in unintended contexts, increasing the risk of misuse, incorrect geospatial processing, or unsafe assumptions about offline behavior and required data sources.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
Place queries are transmitted to external geocoding services without any visible user-facing warning in this file, which is a privacy transparency problem. In the farmland-productivity context, queried places may correspond to sensitive agricultural locations, making undisclosed third-party disclosure more concerning than in a generic mapping toy example.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
Resolved place queries are cached to disk by default without user-facing warning, which can create silent persistence of sensitive AOI data. Even if only local, this may violate user expectations and increase exposure on shared hosts, developer workstations, or multi-user systems.

Credential Access

High
Category
Privilege Escalation
Content
都优先于默认值。
- **支持 .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
  token 等)放在 skill 之外。
Confidence
99% confidence
Finding
secrets.json

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

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
Confidence
98% confidence
Finding
numpy

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
rasterio
Confidence
98% confidence
Finding
rasterio

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
93% confidence
Finding
numpy

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