Back to skill

Security audit

Ip Geo Toolkit

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent IP geolocation utility, but it sends lookup targets to external services and uses plaintext HTTP for the main geolocation API.

Install only if you are comfortable sending queried IPs, domains, and your public IP to external lookup services. Avoid using it for sensitive asset inventories unless the script is changed to use an HTTPS geolocation provider and stricter input validation.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ip_geo.py:45
Finding

Lookup Targets and Geolocation Results Transmitted over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/ip_geo.py, lines 45-78
Vulnerability Type: Plaintext transmission of potentially sensitive lookup data
Risk Level: Medium

Complete Code Snippet

python
def lookup_ip(ip_address):
    """Look up geolocation for a single IP address using ip-api.com."""
    url = f"http://ip-api.com/json/{ip_address}?fields=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query"
    try:
        req = urllib.request.Request(url, headers={"User-Agent": "IPGeoToolkit/1.0"})
        with urllib.request.urlopen(req, timeout=10) as resp:
            data = json.loads(resp.read().decode())
            if data.get("status") == "fail":
                return {"error": data.get("message", "lookup failed"), "query": ip_address}
            return data
    except (urllib.error.URLError, OSError, json.JSONDecodeError) as e:
        return {"error": str(e), "query": ip_address}


def lookup_batch(ips):
    """Batch lookup using ip-api.com batch endpoint (max 100 per request)."""
    results = []
    # ip-api.com batch: POST up to 100 IPs
    for i in range(0, len(ips), 100):
        batch = ips[i:i+100]
        url = "http://ip-api.com/batch?fields=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query"
        payload = json.dumps(batch).encode("utf-8")
        try:
            req = urllib.request.Request(
                url,
                data=payload,
                headers={
                    "User-Agent": "IPGeoToolkit/1.0",
                    "Content-Type": "application/json",
                },
                method="POST",
            )
            with urllib.request.urlopen(req, timeout=30) as resp:
                data = json.loads(resp.read().decode())
                results.extend(data)

Technical Analysis

Both single and batch geol ...[truncated 2290 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the plaintext endpoints with HTTPS endpoints from a geolocation provider that supports TLS for every required operation:
    python
    url = f"https://secure-provider.example/json/{encoded_target}?fields=..."
    
  2. Retain Python's default TLS certificate and hostname verification; do not introduce an unverified SSL context to bypass certificate errors.
  3. If the selected provider does not offer HTTPS on the applicable service tier, migrate to an HTTPS-capable provider rather than silently falling back to HTTP.
  4. If temporary HTTP compatibility is unavoidable, require explicit user opt-in and display a prominent warning that lookup targets and results can be intercepted or modified.
  5. Validate returned JSON structure and expected field types. This does not replace TLS, but it limits malformed or unexpected response handling.
  6. Apply strict target validation with ipaddress.ip_address() for IP-only inputs. If domain lookup remains supported, validate hostnames and safely encode them before inserting them into URL paths.
  7. Add automated tests that reject non-HTTPS production API URLs and verify that redirects cannot downgrade requests from HTTPS to HTTP.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented purpose does not fully disclose that the skill accepts stdin, reads bulk input from files, and can write results to output files, which expands its effective data-handling surface. Description/behavior mismatches are dangerous because they can cause users or automated systems to authorize a seemingly simple lookup utility without realizing it processes local data and transmits queried IP information externally.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises network, file read, and file write capabilities through its documented commands, but the manifest does not declare any tool scope or permission boundaries. This weakens reviewability and consent because a user or orchestrator cannot easily tell that the skill reads input files, writes output files, and sends data to external services before use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill lacks a clear warning that IP lookups and public-IP discovery send data to third-party services such as ip-api.com and ipify. This creates a privacy and data-governance risk because user IPs, target IP lists, and metadata about the host environment may be disclosed to external providers without explicit notice.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

validate_ip claims to validate IPs/domains but accepts any non-empty string, allowing arbitrary user-controlled input to be embedded directly into outbound lookup requests and reverse-DNS resolution attempts. In this skill context, that weak validation increases the chance of malformed requests, unexpected network access patterns, and abuse as a network-enabled lookup proxy against third-party services.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The module docstring and manifest present reverse DNS as a supported toolkit capability, but reverse DNS is only attempted during formatted single-result display in format_result, not as part of the structured lookup results or bulk JSON output. This creates a mild description/behavior mismatch because one advertised capability is only partially implemented and unavailable in some execution modes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The bulk mode writes lookup results to an arbitrary output path when --output is provided, but this file write has no confirmation prompt and no nearby user-facing warning beyond the argument name. For a code file, file writes should have some visible disclosure unless the action is clearly explained at the point of execution; here the write occurs silently aside from a success message after completion.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.