Back to skill

Security audit

Poi Clean

Security checks for vulnerabilities and agentic risk

Overview

This POI planner is mostly purpose-aligned, but it automatically uses privacy-sensitive location discovery and an unverified sibling search script in ways users should review carefully.

Install only if you are comfortable sending addresses, coordinates, search terms, and possibly your public IP to Amap, OSM/Overpass, Maoyan, IP lookup providers, and the sibling unified-search providers. Keep .env.local limited to the Amap key, verify the sibling unified-search skill yourself, and avoid using automatic nearby/current-location mode if IP privacy matters.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/amap_ip_location.py:35
Finding

Automatic multi-party public IP discovery with VPN-bypass intent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/providers.py:11
Finding

Overbroad secret-file ingestion exposes unrelated environment variables to subprocesses

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/planner.py:448
Finding

Unpinned executable sibling-Skill dependency creates a local supply-chain execution boundary

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
Findings (40)

Tainted flow: 'req' from os.getenv (line 168, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/amap_direction.py (reported line 171)May include surrounding context.

python
req = urllib.request.Request(full_url, method="GET")
        req.add_header("Accept", "application/json")
        ctx = ssl.create_default_context()
        with urllib.request.urlopen(req, timeout=timeout, context=ctx) as resp:
            return json.loads(resp.read().decode("utf-8", errors="replace"))
    except Exception as e:
        return {"error": str(e)}

Tainted flow: 'req' from os.getenv (line 64, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/amap_geocode.py (reported line 65)May include surrounding context.

python
url = f"{GEOCODE_API_URL}?{query_string}"
        
        req = urllib.request.Request(url, headers={"Accept": "application/json"})
        with urllib.request.urlopen(req, timeout=10) as response:
            data = json.loads(response.read().decode("utf-8", errors="replace"))
        
        if data.get("status") != "1":

Tainted flow: 'req' from os.getenv (line 394, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/planner.py (reported line 395)May include surrounding context.

python
try:
        url = f"https://restapi.amap.com/v3/geocode/regeo?location={lon},{lat}&key={key}&radius=1000&extensions=base"
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=5) as resp:
            data = json.loads(resp.read().decode("utf-8"))
        if data.get("status") == "1":
            comp = data["regeocode"]["addressComponent"]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/lessons-2026-06-01.md (reported line 73)May include surrounding context.

md
def _load_env_file():
    """Simple .env.local loader without external dependencies"""
    try:
        env_path = os.path.join(os.path.dirname(__file__), '..', '.env.local')
        with open(env_path, 'r') as f:
            for line in f:
                line = line.strip()

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/amap_direction.py (reported line 18)May include surrounding context.

python
def _load_env_file():
    """Simple .env.local loader without external dependencies"""
    try:
        env_path = os.path.join(os.path.dirname(__file__), '..', '.env.local')
        with open(env_path, 'r') as f:
            for line in f:
                line = line.strip()

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/lessons-2026-06-01.md (reported line 65)May include surrounding context.

md
import socket
from pathlib import Path

# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/amap_direction.py (reported line 14)May include surrounding context.

python
import socket
from pathlib import Path

# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/amap_direction.py (reported line 16)May include surrounding context.

python
import socket
from pathlib import Path

# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/amap_direction.py (reported line 33)May include surrounding context.

python
import socket
from pathlib import Path

# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/amap_geocode.py (reported line 10)May include surrounding context.

python
import socket
from pathlib import Path

# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/providers.py (reported line 11)May include surrounding context.

python
import socket
from pathlib import Path

# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/amap_geocode.py (reported line 12)May include surrounding context.

python
# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():
    with open(ENV_FILE, "r", encoding="utf-8") as f:
        for line in f:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/amap_ip_location.py (reported line 23)May include surrounding context.

python
# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():
    with open(ENV_FILE, "r", encoding="utf-8") as f:
        for line in f:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/providers.py (reported line 13)May include surrounding context.

python
# Load .env.local if exists
SCRIPT_DIR = Path(__file__).parent.resolve()
ENV_FILE = SCRIPT_DIR.parent / ".env.local"
if ENV_FILE.exists():
    with open(ENV_FILE, "r", encoding="utf-8") as f:
        for line in f:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The document explicitly reveals where sensitive credentials are stored, including a search credentials file and an environment file containing an Amap API key. Even without disclosing the secret values themselves, publishing exact storage locations lowers the effort for an attacker or a malicious downstream tool to target and exfiltrate those files, especially in an agentic environment that may read local paths automatically.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document is written entirely in Chinese and includes no indication that language choice is optional or limited to a justified region-specific context. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The template hard-codes Chinese section headers and expected output structure without any indication that language should be chosen based on user preference or locale. This can cause the agent to ignore user language expectations, leading to misleading, inaccessible, or unusable responses, especially in multilingual environments.

Content

No source excerpt is available for this finding.

Unbounded Output

Medium
Category
Output Handling
Confidence
60% confidence
Finding

Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Content

Scanner excerpt · scripts/amap_direction.py (reported line 81)May include surrounding context.

python
def format_transit_detail_lines(details: Optional[Dict], max_parts: int = 0) -> list[str]:
    """Render concise, user-facing transit detail lines.

    max_parts <= 0 means no truncation (render the full route).
    """
    if not details:
        return []

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill generates natural-language output strings entirely in Chinese, such as route summaries and step instructions, with no opt-in or alternative locale support. That creates a language-policy concern because the skill effectively forces a specific language for user-facing output without documenting the restriction or letting the user choose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This Python code sends user-provided addresses and origin/destination coordinates to the external Amap API via HTTP requests, which can reveal sensitive location data. While the module docstrings describe functionality, the operational functions do not provide any user-facing warning, confirmation, or explicit disclosure that location data is transmitted to a third-party service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring states that it supports parsing arbitrary Chinese addresses, which imposes a language/locale expectation in natural language. Because the file does not offer an opt-in choice or explain that the skill is intentionally region-specific, this can violate the language/locale policy for skills that should not force a specific locale implicitly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sends requests to several third-party IP lookup services and then to Amap, disclosing the user's public IP and enabling correlation of network metadata across multiple providers. The explicit goal of finding a 'real (non-VPN) public IP' and preferring a provider that may bypass VPN protections makes this materially more privacy-invasive than ordinary geolocation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module-level documentation says the provider uses typecode-based precise search to replace fuzzy keyword search. However, in the main search flow, when a keyword is supplied, the code explicitly avoids passing any typecode and calls _search_with_typecode(..., None, keywords=keyword), making the actual behavior keyword-only rather than typecode-constrained.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This Python skill contains user-facing natural language in the module docstring and later console output exclusively in Chinese, which effectively imposes a specific language/locale. The policy requires flagging forced language usage when the skill does not offer an explicit language choice or justify the locale restriction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The function transmits user location coordinates and search keywords to the external Amap API, which can reveal sensitive behavioral and geolocation data to a third party. In a skill context, lack of explicit disclosure or consent increases privacy risk because users may not realize their precise location and interests are being sent off-platform.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.