Back to skill

Security audit

Scrape Emails By URL

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says by crawling sites for emails, but it has broad outbound crawling and setup behavior that needs review before installation.

Review before installing. Use only in an isolated environment with restricted outbound network access, avoid internal or sensitive URLs, save outputs only to intended locations, and treat extracted emails as personal/contact data subject to site terms and applicable law. Prefer pinned dependencies or a locked environment before running the setup commands.

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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:20
Finding
Unpinned Executable Third-Party Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:20` and `SKILL.md:123-124` **Vulnerability Type**: Unpinned package and browser-component installation **Risk Level**: Medium ### Vulnerable Code ```bash pip install crawl4ai ``` ```bash pip install crawl4ai playwright install ``` ### Technical Analysis The installation instructions retrieve the latest available `crawl4ai` package and Playwright browser components without pinning reviewed versions or verifying artifact integrity. Python packages can execute code during installation and subsequently run with the privileges of the user invoking the Skill. Playwright also downloads executable browser artifacts from external distribution infrastructure. Because there is no lockfile, hash verification, version constraint, or documented trusted package source, the code installed by following these instructions may change after the Skill has been reviewed. A compromised upstream release, package repository, dependency, or browser artifact could therefore introduce malicious executable code. This finding does not establish that the current `crawl4ai` package or Playwright artifacts are malicious. It identifies the absence of controls needed to make dependency installation reproducible and resistant to supply-chain compromise. ### Attack Path 1. An attacker compromises an upstream package, transitive dependency, package repository, or browser artifact distribution channel. 2. A malicious release becomes the latest version resolved by `pip install crawl4ai` or the browser installer. 3. A user follows the documented setup instructions without version or hash validation. 4. The malicious component executes during installation or when the crawler is launched. 5. The payload gains the same filesystem, network, environment-variable, and process privileges as the user running the installation or Skill. ### Impact Assessment Successful exploitation could permit arbitrary code execution under the installi ...[truncated 317 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `crawl4ai` and all transitive dependencies to reviewed versions in a lockfile. 2. Require package hashes, such as with `pip install --require-hashes -r requirements.txt`. 3. Pin the Playwright version and document the corresponding browser revision. 4. Verify downloaded browser artifacts through checksums or signatures where supported. 5. Use a trusted, explicitly configured package index and prevent fallback to untrusted repositories. 6. Install and execute the Skill in an isolated virtual environment or container under a non-privileged account. 7. Add automated dependency scanning and a controlled update process so version changes receive security review before deployment. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/find_emails.py:26
Finding
Unrestricted Crawl Destinations Allow Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/find_emails.py:26-34`, `scripts/find_emails.py:89-91`, and `scripts/find_emails.py:169-178` **Vulnerability Type**: Server-side request forgery and unsafe URL-scheme handling **Risk Level**: High ### Vulnerable Code ```python def ensure_scheme(url: str) -> str: """Add https:// if URL has no scheme. Returns URL unchanged if scheme present.""" parsed = urlparse(url) if parsed.scheme: return url if url.startswith("//"): return "https:" + url return "https://" + url ``` ```python async with AsyncWebCrawler(config=browser_config) as crawler: for url in urls: pages = await crawler.arun(url=url, config=crawler_config) items = pages if isinstance(pages, list) else [pages] all_pages.extend(items) ``` ```python elif args.urls: url_patterns = load_url_patterns(script_dir) urls = [ensure_scheme(u) for u in args.urls] try: email_sources = asyncio.run(crawl_and_extract( urls=urls, url_patterns=url_patterns, max_depth=args.max_depth, max_pages=args.max_pages, verbose=args.verbose, )) ``` ### Technical Analysis The command-line URL values are forwarded to a headless browser without validating the scheme or destination. `ensure_scheme()` accepts any input that already has a scheme instead of restricting inputs to HTTP and HTTPS. The implementation also does not reject loopback, private, link-local, multicast, reserved, or cloud metadata addresses. The crawler configuration uses `include_external=False`, but this limits links followed during deep crawling; it does not validate the initial destination. The code also does not show redirect-target validation or protection against DNS rebinding. Consequently, a URL that initially appears acceptable could resolve or redirect to an internal address after ...[truncated 2237 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse every input URL and allow only explicit `http` and `https` schemes. 2. Reject URLs containing credentials, malformed hosts, ambiguous numeric IP representations, or unsupported ports. 3. Resolve the hostname before connecting and reject every resolved loopback, private, link-local, multicast, unspecified, and reserved address for both IPv4 and IPv6. 4. Reapply scheme, hostname, port, and resolved-address validation to every redirect destination. 5. Defend against DNS rebinding by connecting to a validated, pinned address or by revalidating the actual address used for each connection. 6. Block known cloud metadata destinations, including link-local metadata addresses, as an additional safeguard. 7. Prefer an explicit hostname allowlist when this Skill is exposed through an Agent or service to untrusted users. 8. Apply outbound firewall or proxy rules so the browser process cannot access internal networks or metadata services. 9. Run the crawler in an isolated container with minimal filesystem access, no sensitive environment variables, and tightly restricted egress. 10. Add tests covering loopback addresses, RFC1918 ranges, IPv6 local addresses, alternate IP encodings, redirects to internal hosts, unsupported schemes, and DNS-rebinding scenarios. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (6)

Lp1

High
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The script performs outbound network crawling via crawl4ai against user-supplied URLs, which is a real network capability. If the skill manifest does not explicitly declare network access, this creates a permission mismatch that can bypass operator expectations and enable unintended requests to arbitrary hosts, including internal or sensitive endpoints if the runtime has such reachability.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The manifest description says to use the skill when 'extracting emails from websites, finding contact information, or crawling for email addresses.' Phrases like 'finding contact information' are broad and could match common user intents beyond this specific crawler, with no negative examples or explicit activation constraints.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill instructs users to crawl websites locally and allows writing outputs to disk, but provides no warning about privacy, legal considerations, or filesystem side effects. In this context, the omission is meaningful because the skill is specifically designed to collect contact data at scale and can persist that data locally without prompting users to consider consent, retention, or safe file handling.

Vague Triggers

Medium
Confidence
96% confidence
Finding
This manifest-style JSON defines wildcard URL patterns such as '*about*', '*team*', and '*support*' without any narrowing context, exclusions, or scope constraints. These terms are common across many unrelated pages, so the activation surface is broad and could cause unintended skill invocation.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The examples demonstrate saving results to local files but do not warn that files may be created or overwritten. This is a smaller issue than the broader privacy omission, but it can still lead to unintended local side effects or accidental exposure of extracted email data if users save to unsafe locations.

Context-Inappropriate Capability

Low
Confidence
94% confidence
Finding
The documentation includes unrelated social media growth and paid follower promotion content in a skill whose purpose is crawling websites for email extraction. This kind of off-topic insertion is suspicious because it can manipulate downstream agent behavior, dilute trust boundaries, and normalize unrelated external services in a context that should stay narrowly scoped.

Static analysis

No suspicious patterns detected.