Back to skill

Security audit

outreach-pipeline

Security checks for vulnerabilities and agentic risk

Overview

This is a real bulk-email sender, but it needs Review because it overstates some compliance safeguards and handles email credentials and recipient logs in risky ways.

Review before installing or using. Use only with contact lists you are authorized to email, send a small confirmed test batch first, prefer scoped provider API keys or app passwords over primary mailbox passwords, avoid passing SMTP passwords on the command line, and treat generated CSV logs as sensitive because they contain recipient data and may contain untrusted cells.

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

Warning
Location
scripts/send.py:98
Finding

SMTP Password Exposed Through Command-Line Arguments

Content
View full analysis
" \ --rate-limit 15 \ --out-log out/send_results.csv ``` ### Technical Analysis Accepting an SMTP password through `--smtp-pass` exposes the secret as part of the process command line. Depending on the operating system and execution environment, command-line arguments may be available through: - Process inspection tools such as `ps` or `/proc//cmdline` - Shell history - CI/CD and automation logs - Terminal-session recording - Process monitoring and endpoint-management systems - Parent-process telemetry The exposure window may be prolonged because the script sleeps between recipient attempts to implement rate limiting. Although SMTP authentication is necessary for the declared functionality, exposing the password through a command-line argument is not necessary and exceeds secure credential-handling requirements. No hardcoded SMTP credential was found, and the password is not intentionally written to the result log. ### Attack Path 1. An operator foll ...[truncated 1329 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/send.py:111
Finding

Spreadsheet Formula Injection Through Unsanitized CSV Result Logs

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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
Findings (14)

Tainted flow: 'api_key' from os.environ.get (line 76, credential/environment) → requests.post (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/send.py (reported line 68)May include surrounding context.

python
"subject": subject,
        "content": [{"type": "text/plain", "value": body}]
    }
    r = requests.post('https://api.sendgrid.com/v3/mail/send', json=payload, headers={'Authorization': f'Bearer {api_key}'})
    if r.status_code >= 300:
        raise RuntimeError(f'SendGrid error: {r.status_code} {r.text}')

Tainted flow: 'domain' from os.environ.get (line 77, credential/environment) → requests.post (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/send.py (reported line 80)May include surrounding context.

python
domain = os.environ.get('MAILGUN_DOMAIN')
    if not api_key or not domain:
        raise RuntimeError('MAILGUN_API_KEY/MAILGUN_DOMAIN not set')
    r = requests.post(f'https://api.mailgun.net/v3/{domain}/messages', auth=('api', api_key), data={
        'from': f"{args.from_name} <{args.from_email}>",
        'to': [to_email],
        'subject': subject,

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill claims compliance, unsubscribe handling, Gmail/Outlook support, and simple sequencing, but the described behavior does not actually implement several of those safeguards and features. This is dangerous because operators may rely on nonexistent protections and send bulk mail without unsubscribe processing, proper provider-specific auth handling, or compliance controls, creating abuse, legal, and account-suspension risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises and instructs use of capabilities that access environment variables, local files, and external networks, but it does not declare any tool scope or permissions boundaries. In an agent setting, this increases the chance of over-broad execution, unintended secret access, or unreviewed network/file operations because callers cannot clearly constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language content of the skill is entirely in Chinese, including the description, usage guidance, and examples, with no indication that users may opt into another language. This can violate language/locale policy when a skill effectively mandates a specific language without user choice or documented justification.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/send.py (reported line 68)May include surrounding context.

python
"subject": subject,
        "content": [{"type": "text/plain", "value": body}]
    }
    r = requests.post('https://api.sendgrid.com/v3/mail/send', json=payload, headers={'Authorization': f'Bearer {api_key}'})
    if r.status_code >= 300:
        raise RuntimeError(f'SendGrid error: {r.status_code} {r.text}')

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/send.py (reported line 68)May include surrounding context.

python
"subject": subject,
        "content": [{"type": "text/plain", "value": body}]
    }
    r = requests.post('https://api.sendgrid.com/v3/mail/send', json=payload, headers={'Authorization': f'Bearer {api_key}'})
    if r.status_code >= 300:
        raise RuntimeError(f'SendGrid error: {r.status_code} {r.text}')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/send.py (reported line 68)May include surrounding context.

python
"subject": subject,
        "content": [{"type": "text/plain", "value": body}]
    }
    r = requests.post('https://api.sendgrid.com/v3/mail/send', json=payload, headers={'Authorization': f'Bearer {api_key}'})
    if r.status_code >= 300:
        raise RuntimeError(f'SendGrid error: {r.status_code} {r.text}')

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/send.py (reported line 80)May include surrounding context.

python
domain = os.environ.get('MAILGUN_DOMAIN')
    if not api_key or not domain:
        raise RuntimeError('MAILGUN_API_KEY/MAILGUN_DOMAIN not set')
    r = requests.post(f'https://api.mailgun.net/v3/{domain}/messages', auth=('api', api_key), data={
        'from': f"{args.from_name} <{args.from_email}>",
        'to': [to_email],
        'subject': subject,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code sends outbound emails to recipients from a CSV via SMTP, SendGrid, or Mailgun, which is a safety-relevant network operation affecting user data and external parties. The script has no confirmation prompt, no per-send user-facing disclosure, and no inline docstring/comment warning about transmitting recipient addresses and message content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file is entirely written in Chinese and does not indicate that users may choose another language or locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The entire markdown file is written in Chinese and does not indicate that language selection is optional or configurable. Under the policy rule for natural-language violations, this can constitute a language/locale constraint when no user choice or justification is provided.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script reads SMTP credentials and third-party API keys to authenticate email delivery, but provides no user-facing notice that credentials from CLI arguments or environment variables will be used. Under the rule, access to sensitive environment variables or credentials should have some visible disclosure unless already clearly documented elsewhere.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script writes recipient email addresses and delivery outcomes to a local CSV log by default, creating a privacy and data-handling risk if the file is stored insecurely or shared unintentionally. In an outreach automation context, this can expose contact lists and campaign metadata, which may be sensitive personal or business information.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.