6 min read

Firecrawl: Turn Any Website into LLM-Ready Data (GitHub, Scanned)

A web data API that searches, scrapes and crawls sites into clean Markdown or JSON for AI agents.

Firecrawl logo
✅
Scan: safe. Nothing malicious. The note is for self-hosters: the Docker Compose stack serves an unauthenticated API by default, so keep it off public networks. Scanned Sep 25, 2026; the full report is below.

Firecrawl turns web pages into something a language model can use. Give it a URL and it returns clean Markdown, HTML, structured JSON or a screenshot, with JavaScript rendered and boilerplate stripped; give it a site and it crawls or maps every page; give it a query and it searches the web and returns the full content of the results. It can click, scroll and type before extracting, parses PDFs and DOCX files, and has an agent endpoint that gathers data from a plain-language request.

It is the most-starred project in its category, at about 185,000 stars, built by the company behind Mendable and offered two ways. The hosted API at firecrawl.dev handles proxies and bot walls and adds features the open-source build lacks; this repository is the same API, AGPL-3.0, that you can run yourself with Docker Compose. SDKs for Python, Node, Go, Java, Rust and PHP are MIT-licensed, and an MCP server and CLI plug it into coding agents.

  • Repository: github.com/firecrawl/firecrawl
  • Licence: AGPL-3.0 (GNU Affero General Public License v3.0)
  • Language: TypeScript. Stars: 185.2K. Forks: 9,935. Last push: Sep 27, 2026.
  • Scan: safe, Sep 25, 2026, commit f75a8d4

Who it is for

Developers building RAG pipelines, research agents or monitoring tools that need web content as clean text, and teams that want the same API self-hosted for cost or data-control reasons.

Getting started

1. Python SDK, for the hosted API (get a key at firecrawl.dev) or your own instance

pip install firecrawl-py

2. Or the Node SDK

npm install firecrawl

3. Self-host: clone and start the Docker Compose stack

git clone https://github.com/firecrawl/firecrawl.git && cd firecrawl && docker compose up -d

4. Scrape a page through your own instance

curl -X POST http://localhost:3002/v2/scrape -H 'Content-Type: application/json' -d '{"url": "firecrawl.dev"}'

The self-hosted API needs no key because it has no authentication by default. The project's own SELF_HOST.md says to keep it on a trusted network until you add authentication, TLS and network policy, and notes the Compose file defines no persistent volumes.

Safety scan

We cloned firecrawl/firecrawl at commit f75a8d4 on Sep 25, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • One secret hit: a private key in apps/api/src/__tests__/snips/v2/scrape-skip-tls.test.ts, named SELF_SIGNED_KEY. The test starts an HTTPS server with a deliberately bad certificate to check the skipTlsVerification option; the key protects nothing. The bare-IP URLs are also tests, including phishing-style examples for the URL canonicalizer.
  • Three pattern hits. apps/api/Dockerfile installs Rust with rustup's official curl | sh at image build time, on the build machine. The other two are in tests and examples: a Java SDK test that uses webhook.site as a placeholder, and a blog notebook quoting Heroku's installer.
  • Install hooks matter only if you build from source: apps/api/native's install script runs pnpm build to compile a Rust module (with its build.rs), and apps/api's prepare script sets up husky git hooks for contributors. One committed binary, the Java SDK's Gradle wrapper jar.
  • 48 known advisories and none critical. The API itself (apps/api/pnpm-lock.yaml, 930 packages) has 1 high and 1 moderate. Most of the rest sit in an example project (9 high), the Rust SDK's Cargo.lock (1 high, rustls-webpki) and unrated entries in the Go HTML-to-Markdown service. Dependabot is configured.
  • 31 workflows, none using pull_request_target, and 33 of 41 third-party actions pinned to a commit, one of the best ratios in this series. Licence and contributing guide present; no security policy file or CodeQL.

What the scanner counted

CheckResult
Secrets1 candidate found and read; see the notes above.
Suspicious code3 pattern hits found and read; every one is listed under the raw findings.
Install-time code2 npm lifecycle scripts. 1 Cargo build script. 1 installer script
Committed binaries1 executable or compiled object committed; listed under the raw findings.
CI workflows31 workflows. None use pull_request_target. 8 of 41 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often firecrawl.dev, docs.firecrawl.dev, api.firecrawl.dev, cloud.google.com. 9 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilities48 advisories across 2,382 pinned packages: 0 critical, 11 high, 22 moderate, 4 low, 11 unrated. apps/api/pnpm-lock.yaml: 930 packages, 2 advisories; apps/api/sharedLibs/go-html-to-md/go.mod: 7 packages, 10 advisories; apps/go-html-to-md-service/go.mod: 12 packages, 11 advisories; apps/js-sdk/firecrawl/pnpm-lock.yaml: 453 packages, 0 advisories; apps/js-sdk/pnpm-lock.yaml: 83 packages, 0 advisories; apps/playwright-service-ts/pnpm-lock.yaml: 128 packages, 0 advisories; apps/rust-sdk/Cargo.lock: 228 packages, 10 advisories; apps/test-site/pnpm-lock.yaml: 430 packages, 0 advisories; apps/test-suite/pnpm-lock.yaml: 438 packages, 1 advisories; apps/ui/ingestion-ui/pnpm-lock.yaml: 325 packages, 0 advisories; examples/deep-research-apartment-finder/requirements.txt: 3 packages, 1 advisories; examples/deepseek-v3-crawler/requirements.txt: 2 packages, 1 advisories; examples/gemini-2.5-web-extractor/requirements.txt: 4 packages, 2 advisories; examples/gpt-4.1-company-researcher/requirements.txt: 3 packages, 2 advisories; examples/gpt-4.1-web-crawler/requirements.txt: 3 packages, 1 advisories; examples/o4-mini-web-crawler/requirements.txt: 3 packages, 1 advisories; examples/scrape_and_analyze_airbnb_data_e2b/package-lock.json: 96 packages, 21 advisories.
Project hygieneHas automated dependency updates, licence file, contributing guide. Missing security policy, CodeQL.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Secret candidates (1, redacted)
WhereRuleMatch
apps/api/src/__tests__/snips/v2/scrape-skip-tls.test.ts:11private-key-----B…--- (27 chars)
Pattern hits (3)
WhereRuleMatch
apps/api/Dockerfile:44download-piped-to-shellRUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path \
apps/java-sdk/src/test/java/com/firecrawl/CrawlTest.java:245exfil-host (test/example).url("https://webhook.site/test")
examples/blog-articles/deploying_web_scrapers/notebook.ipynb:846download-piped-to-shell (test/example)"$ curl https://cli-assets.heroku.com/install.sh | sh # Linux\n",
URLs to bare IP addresses (9)
WhereRuleMatch
apps/api/src/lib/__tests__/url-utils.test.ts:89ip-literal-urlexpect(hasReachableHost("https://8.8.8.8/")).toBe(true);
apps/api/src/lib/__tests__/url-utils.test.ts:90ip-literal-urlexpect(hasReachableHost("https://93.184.216.34/")).toBe(true);
apps/api/src/lib/__tests__/url-utils.test.ts:92ip-literal-urlexpect(hasReachableHost("https://1.1.1.10:8080/p")).toBe(true);
apps/api/src/lib/threat-protection/providers/web-risk/canonicalize.test.ts:19ip-literal-url"http://168.188.99.26/.secure/www.ebay.com/",
apps/api/src/lib/threat-protection/providers/web-risk/canonicalize.test.ts:22ip-literal-url"http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/",
apps/api/src/lib/threat-protection/providers/web-risk/canonicalize.test.ts:23ip-literal-url"http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/",
apps/api/src/lib/threat-protection/providers/web-risk/canonicalize.test.ts:29ip-literal-url["http://3279880203/blah", "http://195.127.0.11/blah"],
apps/api/src/lib/threat-protection/providers/web-risk/canonicalize.test.ts:138ip-literal-urlexpect(generateUrlExpressions("http://1.2.3.4/1/")).toEqual([
apps/api/src/lib/threat-protection/verdict.test.ts:422ip-literal-url"http://195.127.0.11/",
npm lifecycle scripts (2)
  • apps/api/native/package.json install: pnpm build
  • apps/api/package.json prepare: cd ../.. && husky ./apps/api/.husky
Installer scripts (1)
Committed binaries (1)
  • apps/java-sdk/gradle/wrapper/gradle-wrapper.jar: JAR, 44 KB
Worst known vulnerabilities (24 of 48)
AdvisorySeverityPackageSummary
GHSA-mwp4-54f8-5fhrhighip-address@6.4.0ip-address: Address4 decodes leading-zero octets as decimal while resolvers decode them as octal, allowing SSRF and trus…
GHSA-82j2-j2ch-gfr8highrustls-webpki@0.103.4rustls-webpki: Denial of service via panic on malformed CRL BIT STRING
GHSA-35jp-ww65-95whhighaxios@1.15.2axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `config.proxy`
GHSA-777c-7fjr-54vfhighaxios@1.15.2Allocation of Resources Without Limits or Throttling in Axios
GHSA-gcfj-64vw-6mp9highaxios@1.15.2Axios Node HTTP adapter can use an inherited proxy after interceptor config cloning
GHSA-hfxv-24rg-xrqfhighaxios@1.15.2Axios: Regular Expression Denial of Service (ReDoS) via Cookie Name Injection
GHSA-j5f8-grm9-p9fchighaxios@1.15.2Axios: Proxy-Authorization header leaks to redirect target when proxy is re-evaluated to direct connection
GHSA-p92q-9vqr-4j8vhighaxios@1.15.2Axios: Proxy-Authorization Credential Leak to Origin Server Across HTTP-to-HTTPS Redirect in Axios Node.js HTTP Adapter
GHSA-pjwm-pj3p-43mvhighaxios@1.15.2axios's shouldBypassProxy does not recognize IPv4-mapped IPv6 addresses, allowing NO_PROXY bypass (incomplete fix for CV…
GHSA-hmw2-7cc7-3qxxhighform-data@4.0.5form-data: CRLF injection in form-data via unescaped multipart field names and filenames
GHSA-96hv-2xvq-fx4phighws@8.18.3ws: Memory exhaustion DoS from tiny fragments and data chunks
GHSA-v2v4-37r5-5v8gmoderateip-address@6.4.0ip-address has XSS in Address6 HTML-emitting methods
GHSA-5cv4-jp36-h3mwmoderategolang.org/x/net@0.41.0Go Net HTML parser is vulnerable to denial of service
GHSA-434x-w66g-qw3rmoderatebytes@1.10.1bytes has integer overflow in BytesMut::reserve
GHSA-2mjx-qc3c-rqvcmoderaterustls@0.23.31TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries
GHSA-pwjx-qhcg-rvj4moderaterustls-webpki@0.103.4webpki: CRLs not considered authoritative by Distribution Point due to faulty matching logic
GHSA-7gcf-g7xr-8hxjmoderateserde_with@3.14.0serde_with: KeyValueMap serialization panics on empty sequence or map entries
GHSA-r6v5-fh4h-64xcmoderatetime@0.3.41time vulnerable to stack exhaustion Denial of Service attack
GHSA-8cw4-87c7-c6xxmoderatecsv-parse@4.16.3node-csv: Prototype replacement still reachable via columns path
GHSA-mf9w-mj56-hr94moderatepython-dotenv@1.0.0python-dotenv: Symlink following in set_key allows arbitrary file overwrite via cross-device rename fallback
GHSA-mf9w-mj56-hr94moderatepython-dotenv@1.0.1python-dotenv: Symlink following in set_key allows arbitrary file overwrite via cross-device rename fallback
GHSA-gc5v-m9x4-r6x2moderaterequests@2.32.4Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility function
GHSA-42h9-826w-cgv3moderateaxios@1.15.2Axios: Excessive recursion in formDataToJSON can cause denial of service
GHSA-7q8q-rj6j-mhjqmoderateaxios@1.15.2Axios: Nested axios option objects can consume polluted prototype values

By the numbers

Stars185.2K
Forks9,935
Contributors175
Commits6,389
Open issues87
Open pull requests565
Releases35
Latest releasev2.11.0
LicenceAGPL-3.0
Main languageTypeScript
Project age2 years
Last pushSep 27, 2026
Tracked files1,956
Lines of code399.7K
Checkout size53 MB

Lines by language: TypeScript 263.3K, Python 49.3K, Markdown 15.7K, JSON 14.3K, Rust 12.1K, Jupyter 9,099.

Questions

Is Firecrawl free?

The code is. The server is AGPL-3.0 and free to self-host, and the SDKs are MIT. The hosted API at firecrawl.dev is paid by credits, with a free allowance to start, and includes extras the open-source build lacks, such as its own scraping engine and proxy handling. If you modify the server and offer it to others, the AGPL requires sharing your changes.

Firecrawl or Crawl4AI?

Firecrawl is an API service first: you call endpoints from any language, and self-hosting means running a multi-container stack with Redis, RabbitMQ and PostgreSQL. Crawl4AI is a Python library first that runs a browser inside your own process, with a Docker server as an option. For a hosted API with SDKs, Firecrawl; for crawling inside a Python program, Crawl4AI.

Does Firecrawl respect robots.txt?

By default, yes. The crawler reads each site's robots.txt and skips disallowed URLs, and the code offers an ignoreRobotsTxt option for crawls that override it. The README is explicit that respecting each site's policies and terms is the user's responsibility, which applies equally to a self-hosted instance.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.