Back to skill

Security audit

Cold Email Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but its website-scraping workflow is too broadly scoped and could be used to fetch internal or unsafe URLs before generating outreach emails.

Review this skill before installing. Use it only with trusted public business URLs or a scrubbed lead list, do not point it at internal hosts or private network addresses, and manually review generated emails before sending. Be aware that --save writes business/contact details and generated outreach text to local disk.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
generator.py:18
Finding

Unrestricted URL Scraping Enables Server-Side Request Forgery

Content
View full analysis
str: """Scrape a URL and return its text content.""" try: r = subprocess.run( ["python3", SCRAPE_SCRIPT, "web", url], capture_output=True, text=True, timeout=30 ) if r.returncode != 0 or not r.stdout.strip(): return "" d = json.loads(r.stdout) content = d.get("content", []) if isinstance(content, list): return " ".join(c for c in content if c).strip() return str(content).strip() except Exception as e: print(f" [scrape error] {url}: {e}", file=sys.stderr) return "" def scrape_business(url: str) -> str: """Scrape homepage and try to also grab about/contact subpages.""" base = url.rstrip("/") texts = [] # Homepage print(f" Scraping: {base}", file=sys.stderr) home_text = scrape_url(base) if home_text: texts.append(home_text) # Try common subpages for path in ["/about", "/about-us", "/contact", "/services"]: sub_url = base + path print(f" Scraping: {sub_url}", file=sys.stderr) sub_text = scrape_url(sub_url) if sub_text and len(sub_text) > 100: texts.append(sub_text) combined = " ".join(texts) # Trim to ~2000 chars to keep Ollama prompt manageable return combined[:2000] if combined else "" ``` The command-line input reaches this code without destination validation: ```python elif args.name and args.url: process_business(args.name, args.url, args.phone, args.save) ``` ### Technical Analysis The application passes a user-controlled URL, or a URL parsed from the local lead list, directly to an external scraping process. It does not validate: - The URL scheme. - The destination hostname or IP addre ...[truncated 2235 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
generator.py:60
Finding

Untrusted Website Content Is Directly Embedded in an LLM Instruction Prompt

Content
View full analysis
str: """Use Ollama llama3.2 to generate a cold email.""" if scraped_content: context_section = f"Here's what their website says: {scraped_content}" else: context_section = "No website content was available, but use what you know about businesses in their industry." prompt = ( f"Write a cold email FROM Jay Jimenez at White Lighter Club Studios " f"TO the owner of {business_name}. " f"You are pitching Gracie, an AI receptionist service ($299 setup + $399/mo). " f"{context_section} " f"IMPORTANT: Address the email to 'Hi [their business name] team,' or 'Hi there,' — NOT to Jay. Jay is the SENDER not the recipient. " f"Write 3 short paragraphs: " f"(1) Open with one specific detail about their business that shows you did your homework. " f"(2) Mention the missed call problem — every unanswered call is a lost customer. " f"(3) Introduce Gracie: AI receptionist, $299 setup + $399/mo flat, no contracts. " f"End with: 'Call (347) 851-1505 right now — hear her answer live.' " f"Keep it under 150 words total. No fluff. Sound like a real human, not a salesman. " f"Sign off: Jay Jimenez, White Lighter Club Studios." ) print(f" Generating email via Ollama...", file=sys.stderr) try: r = subprocess.run( ["ollama", "run", "llama3.2", prompt], capture_output=True, text=True, timeout=120 ) email = r.stdout.strip() ``` ### Technical Analysis Website text is attacker-controlled content. The code concatenates that content into the same prompt as the application's behavioral instructions, without a strong trust boundary, structured data extraction, ...[truncated 2040 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly states it scrapes third-party business websites and extracts business details to generate personalized outreach, but it does not warn the operator about that data collection behavior or the legal/privacy implications of using scraped content for unsolicited emails. In a sales-outreach skill, this omission increases the risk of undisclosed collection and use of third-party business information, which can lead to compliance, consent, and reputational issues.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description understates the real behavior: the code not only scrapes a website and drafts one email, but also parses an internal leads database and supports bulk outreach generation. This mismatch is dangerous because users may authorize the tool under incomplete assumptions, leading to broader data access and automated actions than expected.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script accesses an internal master leads file and uses it for bulk processing even though the stated purpose suggests single-site scraping and email generation. This expands the data scope to internal business contact data without clear disclosure or minimization, increasing the chance of unintended mass processing or privacy/compliance issues.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · generator.py (reported line 23)May include surrounding context.

python
def scrape_url(url: str) -> str:
    """Scrape a URL and return its text content."""
    try:
        r = subprocess.run(
            ["python3", SCRAPE_SCRIPT, "web", url],
            capture_output=True, text=True, timeout=30
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · generator.py (reported line 87)May include surrounding context.

python
print(f"  Generating email via Ollama...", file=sys.stderr)
    try:
        r = subprocess.run(
            ["ollama", "run", "llama3.2", prompt],
            capture_output=True, text=True, timeout=120
        )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

In bulk mode, website content is scraped and then transmitted to an external/local model runtime without an explicit warning about data handling, provenance, or possible retention/logging. Because the content source is external and may include sensitive or adversarial text, silent transmission increases privacy and prompt-injection risk in the skill context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation notes that --save writes generated outreach emails into an internal directory, but it does not clearly warn users that running the command persists data to disk. This can lead to accidental retention of generated content, possible exposure of sensitive lead information in local files, and unintended inclusion in backups or shared directories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The save path writes lead-associated business and phone data plus generated outreach text to a local outreach directory with only a flag-based control and no explicit warning about persistence. While this is not covert exfiltration, it can create unintended local data retention and operational/privacy issues if users do not realize records are being stored.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.