Skip to content
Report library
Purpose / Other

Firecrawl Monitor Skill Security Audit

What the author says it does (original text)

|

Independent security check

Security risks found

Files checked
3
Risks found
5
Could it run dangerous commands?Looks for programs run straight after downloading, remote control of your computer, and hidden commands.No risks found
Could it expose your files or keys?Looks for uploads of files containing passwords or keys, and keys written directly in the code.Risks found: 2
Medium risk

Page content and historical snapshots are processed and retained by Firecrawl

Source references: 4
What we found

Monitoring, diffing, and judging occur on Firecrawl's servers, with snapshots retained for diffing; the feature is explicitly unavailable to zero-data-retention teams.

Why this matters

For private, token-bearing, personal, or commercially sensitive pages, content, extracted fields, and change history may leave the user's environment and remain in a third-party system.

The Skill explicitly says Firecrawl performs fetching, diffing, judging, and notification server-side, retains snapshots for comparison, and cannot be used by zero-data-retention teams. Monitored page content therefore leaves the local environment and may be stored. Before enabling it, users should check whether pages contain sensitive or restricted information and confirm retention, access controls, and deletion behavior with the provider.

SKILL.md:12In the instructionsOpen original file
Detect when content on a website changes and get notified by webhook or email. Firecrawl handles fetching, diffing, judging, and notifying server-side. Each page in a check is labeled `same`, `new`, `changed`, `removed`, or `error`.
Show 3 other places
SKILL.md:67In the instructionsOpen original file
- Each check uses credits for its underlying scrape, crawl, or search, plus optional judging. See [Monitoring pricing](https://docs.firecrawl.dev/features/monitoring#pricing).- Minimum schedule interval is **5 minutes**. Monitoring is **not available for zero-data-retention teams**.- **Prefer one monitor over repeated one-off scrapes** whenever the user wants the same URL checked more than once.
SKILL.md:72In the instructionsOpen original file
- **`firecrawl monitor run <id>`** triggers a check immediately — useful for smoke-testing a monitor right after creating it.- **`--retention-days`** controls how long snapshots are kept for diffing. Lower it for high-frequency monitors to save storage.- **External email recipients must opt in.** First time they're added, Firecrawl sends a confirmation email and they only receive alerts after they confirm. Team-owned addresses are auto-confirmed. Once a recipient unsubscribes, they must be re-added by the owner for a fresh confirmation email.
json-tracking.md:46In the instructionsOpen original file
Each changed page in the check response then carries a per-field diff plus a snapshot of the current full extraction:
Medium risk

Change data may be sent to a mistaken or untrusted webhook or email recipient

Source references: 3
What we found

Monitors can notify a supplied email address or webhook. Email has a confirmation process, but the documented webhook flow does not mention recipient verification, content filtering, or confirmation before sending.

Why this matters

A mistyped, substituted, or third-party-controlled webhook could receive page changes, extracted fields, and information about the monitored target.

What this evidence establishes

The source supports sending notifications to a user-specified webhook or email, and external email recipients must opt in. However, the shown addresses are obvious placeholders, and the source neither directs bypassing confirmation or selecting an unknown recipient nor specifies the notification payload. Misdelivery or disclosure depends on the actual configuration. Users can require confirmation of the final recipient, webhook domain, and fields sent, and restrict delivery to endpoints they control.

This assessment concerns the code and conditions shown, not proof that harm has occurred.
SKILL.md:41In the instructionsOpen original file
# Webhook notificationsfirecrawl monitor create --name "Docs webhook" --schedule "every 30 minutes" \  --goal "Alert when docs content changes." \  --page https://example.com/docs \  --webhook-url https://example.com/hook \  --webhook-events monitor.page,monitor.check.completed
Show 2 other places
SKILL.md:73In the instructionsOpen original file
- **`--retention-days`** controls how long snapshots are kept for diffing. Lower it for high-frequency monitors to save storage.- **External email recipients must opt in.** First time they're added, Firecrawl sends a confirmation email and they only receive alerts after they confirm. Team-owned addresses are auto-confirmed. Once a recipient unsubscribes, they must be re-added by the owner for a fresh confirmation email.- **On HTTP 429 / rate-limit errors, back off once**: wait ~30s and retry once. If it persists, stop, report the rate limit as the blocking reason, and delete any monitors created for this task. Never retry in a loop.
json-tracking.md:5In the instructionsOpen original file
By default monitors diff each page's markdown and return a unified text diff. JSON-mode change tracking returns keyed per-field diffs instead — e.g. `plans[0].price: "$19/mo" → "$24/mo"` — which drop straight into a Slack message, CI step, or internal tool. The CLI flags don't cover this — pass a JSON body via positional file or piped stdin:
Could it delete files or keep running?Looks for broad file deletion, disk overwrites, and programs set to start automatically.No risks found
Could it bypass safety checks?Looks for skipped website security checks, excessive file access, or actions that skip your approval.Risks found: 1
Low risk

The install command does not pin a dependency version

Source references: 2
What we found

The installation command does not specify dependency versions. The same command may download different code later, so what you install can differ from what was checked.

Why this matters

A later install may download different code even though the command and this report have not changed.

Legitimate use of this code

Line 7 only permits invocations of `npx firecrawl-cli`; it is not an installation command and shows no `install`, package download, or dependency resolution. This does not establish that an unpinned version will be installed. A user can still ask the author to document the supported CLI version.

This assessment concerns the code and conditions shown, not proof that harm has occurred.
SKILL.md:7In the instructionsOpen original file
  - Bash(firecrawl *)  - Bash(npx firecrawl-cli *)---
Show 1 other places
SKILL.md:5In the instructionsOpen original file
  Alert by webhook/email on web changes — use for "monitor/watch/track/alert me when": recurring checks on known URLs (prefer over repeated one-off scrapes) or web-wide watches for new results (queries + goal).allowed-tools:  - Bash(firecrawl *)  - Bash(npx firecrawl-cli *)---
Could it mislead the AI or hide text?Checks the skill instructions for requests to ignore you, influence the report, or hide text in invisible characters.Risks found: 1
Medium risk

Adversarial page text may influence the AI change judge

Source references: 3
What we found

Page content is supplied to an AI judge that decides `changed` versus `same`, while the provided instructions do not describe treating page text as untrusted data or isolating embedded prompt-injection text.

Why this matters

An attacker-controlled page could try to suppress genuine changes or create false alerts, misleading operational, pricing, inventory, or competitive-intelligence decisions.

What this evidence establishes

The source says an AI judge uses the goal to classify a page as changed or same, so page content does enter an AI decision process. But there is no visible evidence that page text is treated as executable instruction, nor that scripts, tool calls, or account actions are controlled by this judge; the shown impact is limited to classification and alert accuracy. Users can ask whether page-borne prompts are isolated and keep results advisory rather than connected to high-impact automation.

This assessment concerns the code and conditions shown, not proof that harm has occurred.
goals.md:7In the instructionsOpen original file
The goal is what the AI change judge uses to decide whether a page is `changed` vs `same`. Convert the user's intent into a concise 2-3 sentence goal:
Show 2 other places
SKILL.md:12In the instructionsOpen original file
Detect when content on a website changes and get notified by webhook or email. Firecrawl handles fetching, diffing, judging, and notifying server-side. Each page in a check is labeled `same`, `new`, `changed`, `removed`, or `error`.
goals.md:11In the instructionsOpen original file
- Restate any scope they mentioned: top N, price, role type, region, company, topic, status, or a specific entity.- Add an `Ignore ...` sentence **only** for intent-specific exclusions (e.g. points/comments for rankings, marketing copy for pricing, general company-page updates for job listings). The judge already handles generic noise — whitespace, casing, punctuation, encoding, formatting-only changes, request/session IDs, cache busters, tracking params, generic metadata, and unrelated page chrome — so leave those out.- Include only page-specific sections, entities, thresholds, exclusions, or business rules the user actually mentioned.- If the user is vague or asks for "any change", keep the goal broad with no exclusions. If the user mentions noise they do not care about, include that explicitly.
Could it change links or payment recipients without asking?Looks for forced referral or payment changes combined with instructions to hide the change.Risks found: 1
Medium risk

Persistent monitors can continue consuming paid credits

Source references: 5
What we found

Every scheduled check consumes credits for scraping, crawling, or searching and may add AI-judging costs; fresh scraping is the default. A created monitor continues until paused or deleted.

Why this matters

Frequent schedules, whole-site crawls, multiple queries, or forgotten long-running monitors may cause ongoing and unexpectedly high charges. The required smoke test also launches an immediate check.

This is persistent scheduled monitoring. Every check consumes scrape, crawl, or search credits and may add judging costs; by default each check performs a fresh scrape. Future runs stop only when the monitor is paused or deleted. An overly frequent or forgotten monitor can therefore keep incurring costs. Users can require the minimum necessary frequency, spending limits or alerts, and explicit pause or deletion when monitoring ends.

SKILL.md:60In the instructionsOpen original file
**Done when:** `create` returns a monitor ID and a smoke-test `run` + `check` confirms the expected target, state, and notification configuration.
Show 4 other places
SKILL.md:66In the instructionsOpen original file
- Each check uses credits for its underlying scrape, crawl, or search, plus optional judging. See [Monitoring pricing](https://docs.firecrawl.dev/features/monitoring#pricing).- Minimum schedule interval is **5 minutes**. Monitoring is **not available for zero-data-retention teams**.- **Prefer one monitor over repeated one-off scrapes** whenever the user wants the same URL checked more than once.
SKILL.md:69In the instructionsOpen original file
- **Prefer one monitor over repeated one-off scrapes** whenever the user wants the same URL checked more than once.- **Silence temporarily with `update --state paused`**; reserve `delete` for monitors that are permanently done. (`--state` is an update flag; `--status` is the global CLI status flag.)- **Filter check pages with `--page-status changed`** (or `new`, `removed`, `error`) to skip the noise from `same` pages.
SKILL.md:75In the instructionsOpen original file
- **On HTTP 429 / rate-limit errors, back off once**: wait ~30s and retry once. If it persists, stop, report the rate limit as the blocking reason, and delete any monitors created for this task. Never retry in a loop.- **Monitor-triggered scrapes default `maxAge` to `0`** — every check performs a fresh scrape unless `scrapeOptions.maxAge` is set explicitly in a JSON payload.
SKILL.md:68In the instructionsOpen original file
- Minimum schedule interval is **5 minutes**. Monitoring is **not available for zero-data-retention teams**.- **Prefer one monitor over repeated one-off scrapes** whenever the user wants the same URL checked more than once.- **Silence temporarily with `update --state paused`**; reserve `delete` for monitors that are permanently done. (`--state` is an update flag; `--status` is the global CLI status flag.)- **Filter check pages with `--page-status changed`** (or `new`, `removed`, `error`) to skip the noise from `same` pages.

Inside this skill

3 instruction sections

The Skill creates persistent monitors on Firecrawl's servers; the service performs fetching, diffing, AI judging, and notification rather than only reading pages locally.

View source
SKILL.md:12In the instructionsOpen original file
Detect when content on a website changes and get notified by webhook or email. Firecrawl handles fetching, diffing, judging, and notifying server-side. Each page in a check is labeled `same`, `new`, `changed`, `removed`, or `error`.

It can monitor one page, a URL list, an entire crawled site, or web-wide search results, and can notify by email or webhook. Web-search mode reruns its queries on every check.

View source
SKILL.md:18In the instructionsOpen original file
| ----------- | ------------------------------ | ------------------------------------------------------ || Single page | `--page <url>`                 | one URL, for changes                                   || URL batch   | `--scrape-urls <url,url,...>`  | several URLs, for changes                              || Whole site  | `--crawl-url <root-url>`       | every page a crawl discovers, for changes              || Web search  | `--queries <q,...>` + `--goal` | the **whole web**, for _new_ results matching the goal |
SKILL.md:23In the instructionsOpen original file
The first three watch URLs you already have. **Web search** runs your queries each check and alerts on results it hasn't seen before (labeled `new` once, `same` on later checks); `--goal` is required with `--queries`.

Structured mode extracts page fields into JSON, retains a current snapshot, and produces per-field differences; the documentation explicitly describes routing these results into Slack, CI, or internal tools.

View source
json-tracking.md:5In the instructionsOpen original file
By default monitors diff each page's markdown and return a unified text diff. JSON-mode change tracking returns keyed per-field diffs instead — e.g. `plans[0].price: "$19/mo" → "$24/mo"` — which drop straight into a Slack message, CI step, or internal tool. The CLI flags don't cover this — pass a JSON body via positional file or piped stdin:
json-tracking.md:46In the instructionsOpen original file
Each changed page in the check response then carries a per-field diff plus a snapshot of the current full extraction:

The workflow calls for an immediate check after creation; if rate limiting persists, it deletes monitors created for the task instead of leaving them paused.

View source
SKILL.md:60In the instructionsOpen original file
**Done when:** `create` returns a monitor ID and a smoke-test `run` + `check` confirms the expected target, state, and notification configuration.
SKILL.md:74In the instructionsOpen original file
- **External email recipients must opt in.** First time they're added, Firecrawl sends a confirmation email and they only receive alerts after they confirm. Team-owned addresses are auto-confirmed. Once a recipient unsubscribes, they must be re-added by the owner for a fresh confirmation email.- **On HTTP 429 / rate-limit errors, back off once**: wait ~30s and retry once. If it persists, stop, report the rate limit as the blocking reason, and delete any monitors created for this task. Never retry in a loop.- **Monitor-triggered scrapes default `maxAge` to `0`** — every check performs a fresh scrape unless `scrapeOptions.maxAge` is set explicitly in a JSON payload.
Start here · InstructionsSKILL.md
firecrawl-monitor
Lines connect the instruction file to its sections, not an observed execution order. Select a section to read the source.

File reference map

References: 4
Files making referencesReferenced content
Lines show actual file references, not execution order. Select a node to highlight its connections and inspect the files and source locations. Dashed lines include files that still need locating.
Files and check records3 files

Coverage and gaps

Content covered in each file

These are the source ranges included in this check, not a guarantee that every issue has been resolved.

  • SKILL.mdFull text included
  • goals.mdFull text included
  • json-tracking.mdFull text included

This report is for the version above. We read the available code and instructions without running the skill or checking extra packages it installs. This is not a promise of safety: a different version or setup may behave differently.

  • SKILL.mdInstructions
  • goals.mdSupporting file
  • json-tracking.mdSupporting file

Operations mentioned in code and instructions

Run commands
SKILL.md:6In the instructionsOpen original file
allowed-tools:  - Bash(firecrawl *)  - Bash(npx firecrawl-cli *)
SKILL.md:7In the instructionsOpen original file
  - Bash(firecrawl *)  - Bash(npx firecrawl-cli *)---
SKILL.md:27In the instructionsOpen original file
```bash# Single page, natural-language schedule, email alert
Install extra software packages
SKILL.md:7In the instructionsOpen original file
  - Bash(firecrawl *)  - Bash(npx firecrawl-cli *)---
Connect to websites
SKILL.md:31In the instructionsOpen original file
  --goal "Alert when a new blog post is published." \  --page https://example.com/blog \  --email alerts@example.com
SKILL.md:44In the instructionsOpen original file
  --goal "Alert when docs content changes." \  --page https://example.com/docs \  --webhook-url https://example.com/hook \
SKILL.md:45In the instructionsOpen original file
  --page https://example.com/docs \  --webhook-url https://example.com/hook \  --webhook-events monitor.page,monitor.check.completed
Read files
json-tracking.md:8In the instructionsOpen original file
```bashcat > pricing-monitor.json <<'EOF'{
json-tracking.md:43In the instructionsOpen original file
firecrawl monitor create pricing-monitor.json# or: cat pricing-monitor.json | firecrawl monitor create```
Lines read
199
File checksum (to compare versions)
67d27cd4ac37d00d8dda6cc3fbf78a4a12843857a3bfe5952ea13270e44c6984