Back to skill

Security audit

Firecrawl Search

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward Firecrawl helper that sends searches and URLs to Firecrawl using the user's API key, with privacy caveats but no hidden or destructive behavior found.

Install only if you intend to use Firecrawl as an external web search/scraping service. Do not submit secret-bearing URLs, internal-only links, authenticated pages, customer data, or regulated content unless your organization approves sharing that information with Firecrawl. Keep the API key out of source control and rotate it if exposed.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
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 (18)

Tainted flow: 'req' from os.environ.get (line 58, credential/environment) → urllib.request.urlopen (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/crawl.py (reported line 46)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode())
    except HTTPError as e:
        print(f"Error: {e.code} - {e.reason}", file=sys.stderr)

Tainted flow: 'req' from os.environ.get (line 58, credential/environment) → urllib.request.urlopen (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/crawl.py (reported line 63)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode())
    except HTTPError as e:
        print(f"Error: {e.code} - {e.reason}", file=sys.stderr)

Tainted flow: 'req' from os.environ.get (line 28, credential/environment) → urllib.request.urlopen (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/scrape.py (reported line 39)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            result = json.loads(resp.read().decode())
            return result
    except HTTPError as e:

Tainted flow: 'req' from os.environ.get (line 27, credential/environment) → urllib.request.urlopen (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/search.py (reported line 38)May include surrounding context.

python
)
    
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read().decode())
            return result
    except HTTPError as e:

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code chunk accurately matches the web search portion of the description and correctly uses the declared FIRECRAWL_API_KEY environment variable. However, the declared purpose is broader than the actual implementation: there is no code for scraping pages, rendering or handling JS-heavy page extraction, crawling full sites, or extracting structured data. This is a description-to-behavior mismatch because the description claims multiple capabilities that are not present in the supplied code.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises network access and use of an environment-sourced API key, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization and review gap: operators and users cannot easily tell what capabilities the skill is expected to use, which increases the chance of unintended network access or secret handling without clear policy constraints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description does not warn users that submitted URLs, search queries, and potentially scraped page contents are sent to an external third-party service. This can lead to accidental disclosure of sensitive internal URLs, tokens embedded in URLs, proprietary content, or regulated data if a user assumes processing is local.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script forwards user-supplied URLs to Firecrawl, a third-party external service, without any explicit warning or consent step at runtime. In an agent-skill context, this can cause unintended disclosure of sensitive internal URLs, query parameters, or target resources to an external provider when users may assume scraping is local.

Content

No source excerpt is available for this finding.

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 · references/api.md (reported line 14)May include surrounding context.

md
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

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 · references/api.md (reported line 29)May include surrounding context.

md
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

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 · references/api.md (reported line 45)May include surrounding context.

md
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

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 · references/api.md (reported line 63)May include surrounding context.

md
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

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/crawl.py (reported line 19)May include surrounding context.

python
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

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/crawl.py (reported line 56)May include surrounding context.

python
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

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/scrape.py (reported line 20)May include surrounding context.

python
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

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/search.py (reported line 18)May include surrounding context.

python
print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    
    url = "https://api.firecrawl.dev/v1/search"
    
    data = json.dumps({
        "query": query,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The request payload forces lang to en and country to us, which imposes a specific language/locale policy on all searches. The script does not offer a user opt-in or configuration mechanism for other locales, and there is no documented justification that this is a region-specific tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The prerequisites instruct users to place an API key in the environment or a .env file but provide no guidance on secure credential handling. This increases the risk of accidental key exposure through shell history, checked-in .env files, logs, screenshots, or insecure local storage practices.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.