Esri Workflow Smell Detector (Consumer)

Security checks across malware telemetry and agentic risk

Overview

The skill appears purpose-built for a paid ESRI project analysis API, but it uploads local project data and uses a wallet private key with limited guardrails.

Review before installing. Use only a dedicated low-balance wallet, avoid custom endpoints unless you fully trust them, inspect and redact project_snapshot.json before upload, and consider pinning or auditing dependencies before running it on proprietary GIS projects.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Tainted flow: 'body' from open (line 127, file read) → requests.post (network output)

High
Category
Data Flow
Content
}

    # Step 1: get 402 challenge
    r1 = requests.post(args.endpoint, json=body, headers={"Accept": "application/json"}, timeout=30)
    if r1.status_code == 200:
        print(json.dumps(r1.json(), indent=2))
        return 0
Confidence
96% confidence
Finding
r1 = requests.post(args.endpoint, json=body, headers={"Accept": "application/json"}, timeout=30)

Tainted flow: 'body' from open (line 127, file read) → requests.post (network output)

High
Category
Data Flow
Content
# Step 2: pay and retry
    x_payment = make_x_payment(challenge, wallet, private_key)
    r2 = requests.post(args.endpoint, json=body, headers={"X-Payment": x_payment, "Accept": "application/json"}, timeout=30)
    print(f"Response: {r2.status_code}")
    ct = (r2.headers.get("content-type") or "").lower()
    if "application/json" in ct:
Confidence
96% confidence
Finding
r2 = requests.post(args.endpoint, json=body, headers={"X-Payment": x_payment, "Accept": "application/json"}, timeout=30)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill describes capabilities to read files, access environment variables, and make network requests, but it does not declare permissions or provide explicit guardrails around those operations. In a paid consumer skill that handles wallet credentials and transmits project snapshots to a remote endpoint, missing permission declarations reduces transparency and increases the chance of overbroad or unexpected access by an agent runtime.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs users to export a blockchain private key and wallet address as environment variables without any security warning or handling guidance. Private keys are highly sensitive secrets; encouraging direct shell export in documentation can lead to credential exposure through shell history, process inspection, logs, shared terminals, or misconfigured environments, potentially resulting in wallet compromise and financial loss.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    # Step 1: get 402 challenge
    r1 = requests.post(args.endpoint, json=body, headers={"Accept": "application/json"}, timeout=30)
    if r1.status_code == 200:
        print(json.dumps(r1.json(), indent=2))
        return 0
Confidence
94% confidence
Finding
requests.post(args.endpoint, json=

External Transmission

Medium
Category
Data Exfiltration
Content
# Step 2: pay and retry
    x_payment = make_x_payment(challenge, wallet, private_key)
    r2 = requests.post(args.endpoint, json=body, headers={"X-Payment": x_payment, "Accept": "application/json"}, timeout=30)
    print(f"Response: {r2.status_code}")
    ct = (r2.headers.get("content-type") or "").lower()
    if "application/json" in ct:
Confidence
94% confidence
Finding
requests.post(args.endpoint, json=

External Transmission

Medium
Category
Data Exfiltration
Content
def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("snapshot", help="Path to project_snapshot.json")
    ap.add_argument("--endpoint", default="https://api.x402layer.cc/e/esri-smells")
    args = ap.parse_args()

    private_key, wallet = load_creds()
Confidence
93% confidence
Finding
https://api.x402layer.cc/

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
eth-account>=0.10.0
Confidence
95% confidence
Finding
requests>=2.28.0

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
eth-account>=0.10.0
Confidence
95% confidence
Finding
eth-account>=0.10.0

Known Vulnerable Dependency: requests — 10 advisory(ies): CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); 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) +7 more

High
Category
Supply Chain
Confidence
98% confidence
Finding
requests

Known Vulnerable Dependency: eth-account — 1 advisory(ies): CVE-2022-1930 (Regular expression denial of service in eth-account)

Low
Category
Supply Chain
Confidence
88% confidence
Finding
eth-account

VirusTotal

66/66 vendors flagged this skill as clean.

View on VirusTotal