Back to skill

Security audit

IG Realtor Recruiting Outreach

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed local CSV-to-outreach generator, with privacy and spreadsheet-export cautions users should handle before using real lead data.

Use only lawfully obtained lead data, minimize stored profile details, review messages manually before sending, and treat generated CSV files as untrusted if opened in spreadsheet software because formula-like input values may not be neutralized.

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/build_ig_recruiting_outreach.py:134
Finding
Untrusted CSV Fields Are Exported Without Spreadsheet Formula Neutralization## Vulnerability Details **File Location**: `scripts/build_ig_recruiting_outreach.py`, lines 134-155 **Vulnerability Type**: CSV formula injection **Risk Level**: Medium ### Vulnerable Code ```python def write_messages_csv(path: Path, campaign: str, sequences: List[Dict[str, object]]) -> None: with path.open("w", encoding="utf-8", newline="") as f: writer = csv.DictWriter( f, fieldnames=[ "campaign", "instagram_handle", "target_brokerage", "stage", "message", ], ) writer.writeheader() for seq in sequences: lead = seq["lead"] # type: ignore[index] for item in seq["messages"]: # type: ignore[index] writer.writerow( { "campaign": campaign, "instagram_handle": lead["handle"], "target_brokerage": lead["target_brokerage"], "stage": item["stage"], "message": item["message"], } ) ``` ### Technical Analysis The function writes values derived from command-line arguments and the input lead CSV directly into an output CSV. In particular, `campaign` and `lead["target_brokerage"]` are not neutralized before export. CSV quoting performed by Python's `csv` module protects the file structure but does not prevent spreadsheet formula interpretation. When a cell begins with a formula indicator such as `=`, `+`, `-`, or `@`, spreadsheet software may process it as a formula rather than plain text. Leading tab or carriage-return characters can also be used to bypass incomplete validation. An attacker who can influence a lead record could therefore provide a crafted `target_brokerage` value. The generated `messages_<campaign>.csv` would retai ...[truncated 1453 chars]
Remediation
## Remediation Suggestions Introduce a centralized CSV-cell neutralization function and apply it to every untrusted or externally influenced field before calling `writer.writerow()`. The hardening function should: 1. Treat values beginning with `=`, `+`, `-`, or `@` as potentially dangerous. 2. Also account for leading tabs, carriage returns, line feeds, and whitespace followed by a formula indicator. 3. Prefix dangerous values with an apostrophe or use another neutralization approach documented as safe for the spreadsheet applications supported by the workflow. 4. Preserve the original value separately in JSON if exact, machine-readable source data is required. 5. Apply protection to all exported fields rather than only `target_brokerage`, because future changes may allow additional fields to begin with attacker-controlled content. 6. Add regression tests covering every dangerous prefix, leading whitespace/control characters, quoted payloads, and ordinary benign values. 7. Document that generated CSV files contain untrusted lead data and should be imported with formula execution disabled where possible. Example defensive implementation: ```python FORMULA_PREFIXES = ("=", "+", "-", "@", "\t", "\r", "\n") def safe_csv_cell(value: object) -> str: text = str(value) probe = text.lstrip(" ") if probe.startswith(FORMULA_PREFIXES): return "'" + text return text ``` Every value in the row should then be passed through `safe_csv_cell()` before export. This function should be validated against the behavior of the spreadsheet applications used by campaign operators.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (2)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill instructs the user to run a local script that reads input CSVs and writes multiple output files, but the manifest does not declare any tool scope or permissions. That mismatch reduces transparency and reviewability, making it easier for file access behavior to be introduced or expanded without explicit user awareness or policy gating.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill is designed around Instagram profile data, lead lists, and potentially scraped personal/business information, yet the description and guidance omit a clear privacy warning and data-handling caution. In this context, users may process or export sensitive profile-derived data without understanding consent, platform-policy, or regulatory risks, increasing the chance of improper collection or outreach.