Back to skill

Security audit

Google Maps Leadgen

Security checks for vulnerabilities and agentic risk

Overview

This lead-generation skill is purpose-aligned, but it exports untrusted Google Maps data into CSV/XLSX files without spreadsheet formula protection.

Review before installing or using. This skill is not clearly malicious, but generated CSV/XLSX files may contain formula-like values from external listings; avoid opening exports in spreadsheet clients with external-content or legacy macro features enabled, and prefer a version that sanitizes spreadsheet cells and asks before sending lead files through chat.

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/gmaps_leads_export.py:45
Finding
Spreadsheet Formula Injection in CSV and XLSX Exports## Vulnerability Details **File Location**: `scripts/gmaps_leads_export.py`, lines 45–50, 63–69, and 96–112 **Vulnerability Type**: Spreadsheet formula injection **Risk Level**: Medium ### Vulnerable Code ```python for r in rows: ws.append([r.get(h, "") for h in headers]) ``` ```python with out_path.open("w", newline="", encoding="utf-8") as f: w = csv.DictWriter(f, fieldnames=headers) w.writeheader() w.writerows(rows) ``` ```python name = pl.get("name", "") website = d.get("website", "") rows.append( { "name": name, "address": d.get("formatted_address") or pl.get("formatted_address", ""), "phone": d.get("formatted_phone_number") or d.get("international_phone_number", ""), "website": website, "email": "", # website crawl optional step; keep empty by default "rating": d.get("rating") if d.get("rating") is not None else pl.get("rating", ""), "place_id": pid, "google_maps_url": f"https://www.google.com/maps/search/?api=1&query={quote_plus(name)}&query_place_id={pid}", } ) ``` ### Technical Analysis Business names, addresses, phone numbers, websites, ratings, and place identifiers are obtained from external MCP/Google Maps responses. The script writes these values directly to CSV or XLSX cells without neutralizing spreadsheet formula prefixes. Values beginning with characters such as `=`, `+`, `-`, or `@` may be interpreted as formulas when the export is opened in spreadsheet software. In XLSX output, `openpyxl` can store a string beginning with `=` as a formula rather than literal text. CSV applications may similarly evaluate formula-like fields when opening the file. Consequently, an attacker who can influence a Google Maps listing field could inject a spreadsheet expression into an exported lead record. ### Attack Path 1. An attacker creates or modifies a Google Maps business listing so that an exported field contains a spreadsheet formula, such as a value beginnin ...[truncated 1300 chars]
Remediation
## Remediation Suggestions Introduce a centralized sanitizer and apply it to every externally sourced value before both CSV and XLSX export. 1. Treat values beginning with `=`, `+`, `-`, or `@` as potentially dangerous. Also account for leading tabs, carriage returns, newlines, and whitespace that spreadsheet clients may ignore before formula detection. 2. Prefix dangerous textual values with a single quotation mark or otherwise encode them as literal text. 3. For XLSX output, explicitly set externally sourced cells to text and apply a text number format. Do not rely exclusively on visual formatting to suppress formula evaluation. 4. Preserve trusted, locally constructed hyperlinks only after validating their components. Validate `place_id` before incorporating it into the generated Google Maps URL. 5. Apply the protection to all exported columns, not only the fields currently expected to contain free-form text. 6. Add regression tests covering values such as `=1+1`, `+SUM(1,1)`, `-1+2`, `@SUM(1,1)`, and formula prefixes preceded by tabs or carriage returns. 7. Document that generated spreadsheets contain externally sourced business data and should not be opened with legacy external-content or macro features enabled. A sanitizer can follow this pattern: ```python FORMULA_PREFIXES = ("=", "+", "-", "@") def spreadsheet_safe(value): if value is None: return "" text = str(value) probe = text.lstrip(" \t\r\n") if probe.startswith(FORMULA_PREFIXES): return "'" + text return text ``` Apply `spreadsheet_safe` to every field passed to `csv.DictWriter` and every externally sourced cell appended through `openpyxl`.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill invokes broad capabilities including network access, file export, chat-based file delivery, and an implied shell/python environment, but it does not declare any explicit tool restrictions. That creates an overprivileged execution surface where an agent could use unnecessary tools or handle data in ways the user did not clearly authorize, increasing the risk of unintended exfiltration or filesystem misuse.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The skill is designed to collect, enrich, export, and transmit business lead data, including phone numbers, websites, and potentially discovered email addresses, but it provides no built-in warning or consent checkpoint before sharing files in chat. In this context, silent export and transmission can cause privacy, compliance, or data-handling issues, especially when enrichment pulls contact details that may be regulated or sensitive in some jurisdictions.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def mc_call(tool: str, args: dict, timeout: int = 20):
    p = subprocess.run(
        ["mcporter", "call", tool, "--args", json.dumps(args), "--output", "json"],
        capture_output=True,
        text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.