Back to skill

Security audit

Email Verifier

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but its live SMTP checks can expose email addresses externally and can be steered by DNS to probe internal SMTP services unless run in a constrained environment.

Install only if you are comfortable running live SMTP checks from your machine or agent environment. Use it only on addresses you are authorized to verify, avoid sensitive contact lists unless privacy obligations are understood, and prefer running it in a restricted network or container that cannot reach internal mail services. Pin dnspython before operational use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/verify_email.py:31
Finding

MX Record Injection Enables Blind Internal SMTP Access

Content
View full analysis

Vulnerability Details

File Location: scripts/verify_email.py:31-73
Vulnerability Type: Server-Side Request Forgery through attacker-controlled DNS records
Risk Level: Medium

Vulnerable Code:

python
def get_mx_host(domain):
    """Resolve the highest-priority MX record for a domain."""
    try:
        mx_records = dns.resolver.resolve(domain, 'MX')
        return str(sorted(mx_records, key=lambda x: x.preference)[0].exchange).rstrip('.')
    except dns.resolver.NXDOMAIN:
        return None
    except dns.resolver.NoAnswer:
        return None
    except Exception:
        return None


def verify_email(email, helo_domain="verify.local", timeout=10):
    """
    Verify an email address via SMTP RCPT TO.
    
    Returns dict with:
        email, domain, mx_host, smtp_code, smtp_response, deliverable, error
    
    deliverable values:
        "yes"     - Server accepted the recipient (250)
        "no"      - Server rejected the recipient (550)
        "catch-all" - Server accepts everything (if detected)
        "unknown" - Could not determine (timeout, block, greylisting, etc.)
    """
    domain = email.split('@')[-1].lower()
    result = {"email": email, "domain": domain}

    # Step 1: MX lookup
    mx_host = get_mx_host(domain)
    if not mx_host:
        result["mx_host"] = None
        result["deliverable"] = "unknown"
        result["error"] = "No MX record found"
        return result
    result["mx_host"] = mx_host

    # Step 2: SMTP verification
    try:
        smtp = smtplib.SMTP(timeout=timeout)
        smtp.connect(mx_host, 25)

Technical Analysis

The email domain originates from untrusted command-line, standard-input, or CSV data. The application resolves that domain's MX record and passes the resulting hostname directly to smtplib.SMTP.connect() without validating the destination IP address.

An attacker wh ...[truncated 2083 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse and validate the submitted email address with a standards-aware email parser rather than extracting the domain with split('@').
  2. Resolve every MX hostname to all associated IPv4 and IPv6 addresses.
  3. Reject any address for which Python's ipaddress module reports is_private, is_loopback, is_link_local, is_multicast, is_reserved, or is_unspecified.
  4. Apply an explicit network-destination allow policy where feasible.
  5. Prevent DNS rebinding by connecting to a validated IP address rather than asking SMTP.connect() to resolve the hostname again.
  6. Validate all returned addresses and define secure behavior when a hostname resolves to a mixture of public and prohibited addresses.
  7. Enforce equivalent restrictions at the network layer through outbound firewall or proxy rules.
  8. Avoid returning unnecessary raw SMTP details to untrusted callers, as these details improve internal service enumeration.
  9. Add tests covering loopback, RFC 1918, link-local, reserved, IPv6, mixed-address, and DNS-rebinding scenarios.

T08 · Insecure Dependencies

Note
Location
SKILL.md:25
Finding

Unpinned Dependency Installation Creates Supply-Chain Exposure

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:25-29
Vulnerability Type: Unpinned third-party dependency installed without integrity verification
Risk Level: Low

Vulnerable Code:

markdown
## Dependencies

```bash
pip3 install dnspython
text

The same unsafe installation guidance also appears in the script documentation:

```python
Dependencies: dnspython (pip3 install dnspython)

Technical Analysis

The documented installation command requests dnspython without specifying a reviewed version, lock file, package hash, or trusted package index. The effective dependency can therefore change between installations.

This is not evidence that the current dnspython package is malicious. The risk arises because package selection depends on the state of the configured Python package index at installation time. A compromised package publisher, compromised or untrusted index, unsafe future release, or dependency-resolution change could introduce unintended code.

Python package installation may execute build-related code, and imported package code runs within the privileges of the verifier process. Therefore, dependency integrity is part of the Skill's trusted computing base.

Attack Path

  1. A user or Agent follows the documented pip3 install dnspython command.
  2. pip resolves an unspecified version from the environment's configured package index.
  3. The selected package or index has been compromised, or an unsafe future release has become the latest matching version.
  4. The altered package executes code during installation, build processing, or subsequent import.
  5. That code runs with the filesystem, network, environment-variable, and process permissions of the user installing or invoking the Skill.

Impact Assessment

The exact impact depends on the privileges used for installation and execution. A compromised dependency could access files and credentials available ...[truncated 383 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin dnspython to a specific reviewed version in a dependency file.

  2. Generate and record cryptographic hashes for all accepted distributions.

  3. Install dependencies with hash enforcement, for example:

    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  4. Ensure requirements.txt contains an exact version and approved hashes, for example:

    text
    dnspython==REVIEWED_VERSION --hash=sha256:APPROVED_HASH
    
  5. Regenerate pins and hashes only through a controlled dependency-update and review process.

  6. Document the trusted package index and disallow unexpected extra indexes or mirrors in controlled deployments.

  7. Run dependency vulnerability and provenance checks in continuous integration.

  8. Install and execute the Skill inside a least-privileged virtual environment or isolated container.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents reading user-supplied CSV files and stdin input, which implies file-read capability, but it does not declare any tool scope or permission boundaries. Without explicit allowed-tools or permissions, an agent runtime may grant broader-than-necessary access or make it unclear to reviewers what file access the skill requires, increasing the risk of unintended local file exposure when handling attacker-controlled paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The function performs live SMTP RCPT verification against third-party MX servers using user-supplied email addresses, which discloses those addresses and related metadata to external systems without any explicit privacy notice or consent gate. In this skill’s context, that behavior is the core feature, but it still creates a real privacy and compliance risk because submitted contact lists may contain personal data and can be logged, profiled, or rate-limited by remote mail providers.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.