Skip to main content

Une expression régulière provoque un déni de service et compromet la sécurité de FastAPI

Écrit par
feature python linting

31 juillet 2024

0 minutes de lecture

Bonjour à toutes et à tous ! Dans cet article, nous explorons en profondeur la sécurité des applications, en nous intéressant plus particulièrement à une vulnérabilité susceptible de compromettre la sécurité de FastAPI : le déni de service (DoS) provoqué par des expressions régulières non sécurisées (regex). Nous verrons comment une regex mal conçue peut entraîner un déni de service par expression régulière (ReDoS), une forme d’attaque DoS, et comment identifier et atténuer ces vulnérabilités à l’aide d’un puissant outil de sécurité pour les développeurs : Snyk.

Qu’est-ce qu’une attaque ReDoS ?

ReDoS est une attaque par complexité algorithmique qui provoque un déni de service en utilisant une expression régulière dont l’évaluation prend beaucoup de temps. L’attaquant soumet une chaîne malveillante dans un champ de formulaire web ou un paramètre de requête d’URL, qui est traité par une expression régulière vulnérable. Le temps nécessaire à l’expression régulière pour traiter la chaîne augmente plus vite que de façon polynomiale et, dans de nombreux cas, presque de façon exponentielle par rapport à la taille de l’entrée. Le traitement prend alors beaucoup trop de temps, ce qui entraîne un déni de service.

Comprendre l’impact du ReDoS sur la sécurité de FastAPI en Python

Python, l’un des langages de programmation les plus populaires, possède un vaste écosystème de packages et de bibliothèques. Ceux-ci nous facilitent la vie en tant que développeurs, mais ils peuvent aussi présenter des risques s’ils ne sont pas correctement sécurisés. Avec le rythme effréné du développement logiciel, les packages sont fréquemment mis à jour et de nouvelles versions sont publiées, introduisant parfois des risques de sécurité à notre insu.

L’un de ces risques est la possibilité d’une attaque ReDoS, une forme d’attaque DoS dans laquelle un attaquant fournit à une expression régulière une entrée malveillante dont l’évaluation prend beaucoup de temps. L’application devient alors indisponible ou ralentit considérablement, ce qui peut avoir de graves conséquences : de la dégradation de l’expérience utilisateur à l’interruption complète de l’application.

import re
pattern = re.compile("^(a+)+$")
def check(input):
    return bool(pattern.match(input))
check("a" * 3000 + "!")

Dans le code ci-dessus, l’expression régulière ^(a+)+$ est vulnérable à une attaque ReDoS. Si un attaquant fournit une chaîne composée de « a » suivis d’un caractère différent de « a », l’évaluation de la regex prend beaucoup de temps, provoquant de fait un DoS.

Comment Snyk protège vos applications Python FastAPI

Snyk est un outil de sécurité conçu pour les développeurs, capable d’analyser votre code Python afin de détecter d’éventuelles vulnérabilités ReDoS. Il fournit des rapports détaillés sur les vulnérabilités détectées et recommande les correctifs les plus adaptés.

# After installing Snyk and setting up the Snyk CLI
# you can scan your project:
$ snyk test 

Cette commande analysera le manifeste de vos dépendances tierces, généralement le fichier requirements.txt, et générera un rapport sur toutes les vulnérabilités détectées, y compris les éventuelles vulnérabilités ReDoS. Créez gratuitement un compte Snyk pour commencer dès aujourd’hui à analyser vos projets Python à la recherche de vulnérabilités ReDoS et d’autres failles.

Pour préserver la sécurité d’une application Python, il est essentiel de comprendre l’impact de ces vulnérabilités et de savoir comment les atténuer. C’est là que des outils comme Snyk sont utiles. Snyk Open Source peut vous aider à détecter et à corriger les vulnérabilités de sécurité dans les packages Python, notamment les expressions régulières non sécurisées susceptibles d’entraîner une attaque ReDoS.

Voyons de plus près comment Snyk permet d’identifier et d’atténuer ces vulnérabilités dans les applications web FastAPI en Python.

Vulnérabilité de sécurité FastAPI : CVE-2024-24762

FastAPI est un framework web moderne et performant qui permet de créer des API avec Python à partir des indications de type standard de Python. Sa rapidité et sa capacité à créer facilement et rapidement des API robustes en font un choix populaire auprès des développeurs Python qui doivent concevoir des API RESTful hautes performances.

FastAPI simplifie la création d’API en fournissant directement un mécanisme de routage, la sérialisation et la désérialisation, ainsi que la validation. Il s’appuie sur les projets Python Starlette pour les fonctionnalités web et Pydantic pour la gestion des données. Les développeurs peuvent ainsi tirer parti des fonctionnalités asynchrones disponibles dans Python 3.6 et les versions ultérieures.

Voici un exemple de code permettant de créer une API simple avec une application web FastAPI en Python :

from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
    return {"Hello": "World"}

FastAPI est un outil robuste et agile pour développer des API, mais il n’est pas exempt de vulnérabilités. Il est notamment vulnérable à CVE-2024-24762, une faille de déni de service due à la regex utilisée par le package Python python-multipart.

La dépendance python-multipart est une bibliothèque Python qui analyse les données multipart/form-data. Elle est couramment utilisée comme dépendance dans FastAPI pour gérer les données de formulaire.

Cette vulnérabilité se manifeste lorsqu’un attaquant envoie une chaîne malveillante qui pousse l’expression régulière de python-multipart à consommer une grande quantité de ressources processeur, provoquant ainsi un déni de service (DoS). On parle également de déni de service par expression régulière (ReDoS).

Comment un développeur Python peut-il atténuer cette vulnérabilité ? La première étape consiste à la détecter dans votre projet. Pour cela, vous pouvez utiliser l’outil Snyk CLI.

$ snyk test

Pour détecter des vulnérabilités comme celle-ci, il faut analyser les dépendances de votre projet. Vous obtiendrez ainsi un rapport répertoriant toutes les vulnérabilités présentes dans ces dépendances.

La commande Snyk test signale la vulnérabilité :

snyk test

Testing /Users/lirantal/projects/repos/fastapi-vulnerable-redos-app...

Tested 13 dependencies for known issues, found 1 issue, 1 vulnerable path.

Issues to fix by upgrading dependencies:

  Upgrade fastapi@0.109.0 to fastapi@0.109.1 to fix
  ✗ Regular Expression Denial of Service (ReDoS) (new) [High Severity][https://security.snyk.io/vuln/SNYK-PYTHON-FASTAPI-6228055] in fastapi@0.109.0
    introduced by fastapi@0.109.0

Organization:      liran.tal
Package manager:   pip
Target file:       requirements.txt
Project name:      fastapi-vulnerable-redos-app

Pour corriger la vulnérabilité, vous pouvez passer à des versions plus récentes des packages python-multipart et fastapi dans lesquelles elle a été corrigée. Snyk vous recommande les versions à installer.

Quel est l’impact de la vulnérabilité CVE-2024-24762 sur les applications FastAPI ?

La vulnérabilité CVE-2024-24762 est un exemple hypothétique qui illustre une vulnérabilité ReDoS dans le framework FastAPI. Si un attaquant envoyait une entrée malveillante à un endpoint utilisant une expression régulière vulnérable, l’application FastAPI pourrait consommer des ressources excessives et ne plus répondre, ce qui la rendrait effectivement indisponible.

Développer et compromettre la sécurité de FastAPI : guide étape par étape

Commençons par configurer un nouveau projet Python. Nous devons installer FastAPI ainsi qu’un serveur pour l’héberger. Uvicorn est un bon choix : léger, il fonctionne parfaitement avec FastAPI.

Commencez par installer FastAPI, python-multipart et Uvicorn avec pip :

pip install fastapi==0.109.0 uvicorn python-multipart==0.0.6

Créez ensuite un nouveau répertoire pour votre projet, puis un fichier pour votre application FastAPI dans ce répertoire. Vous pouvez l’appeler main.py.

Écrire le code Python de FastAPI

Nous pouvons maintenant écrire le code de notre application FastAPI. Ouvrez main.py et ajoutez le code Python suivant :

from typing import Annotated
from fastapi.responses import HTMLResponse
from fastapi import FastAPI,Form
from pydantic import BaseModel

class Item(BaseModel):
    username: str

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
async def index():
    return HTMLResponse("Test", status_code=200)

@app.post("/submit/")
async def submit(username: Annotated[str, Form()]):
    return {"username": username}

@app.post("/submit_json/")
async def submit_json(item: Item):
    return {"username": item.username}

Cette application FastAPI simple comporte plusieurs routes (/), dont /submit, qui utilise un formulaire multipart. Lorsqu’une requête POST est reçue, la route submit renvoie le nom d’utilisateur transmis.

Démarrer le serveur et exécuter l’application

Le code de notre application FastAPI est prêt. Nous pouvons maintenant démarrer le serveur Uvicorn et lancer l’application.

Exécutez la commande suivante pour démarrer le serveur :

uvicorn main:app --reload

Un message devrait indiquer que le serveur est en cours d’exécution. Pour tester votre application, accédez à http://localhost:8000 dans votre navigateur web. Le message « Test » devrait s’afficher sur la page.

Compromettre la sécurité de FastAPI avec une attaque ReDoS

Maintenant que notre application FastAPI est en cours d’exécution, nous pouvons rechercher des vulnérabilités. Nous allons utiliser une charge utile d’attaque ReDoS dans la requête HTTP pour exploiter la vulnérabilité du package python-multipart, qui analyse la valeur de l’en-tête content-type.

Si le programme curl est installé, exécutez la commande suivante dans votre terminal :

curl -v -X 'POST' -H $'Content-Type: application/x-www-form-urlencoded; !=\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' --data-binary 'input=1' 'http://localhost:8000/submit/'

Sécuriser votre application FastAPI avec Snyk

Comme vous l’avez vu, les dépendances open source jouent un rôle essentiel dans la création d’applications Python. Toutefois, ces dépendances tierces peuvent parfois être des foyers de vulnérabilités et représenter ainsi d’importantes menaces pour la sécurité. Dans ce contexte, Snyk Open Source est un outil robuste qui aide les développeurs à détecter et à corriger efficacement les problèmes de sécurité.

Imaginez pouvoir repérer rapidement les vulnérabilités de sécurité FastAPI directement dans votre IDE pendant que vous écrivez du code Python, plutôt que d’attendre qu’elles soient détectées plus tard par des outils d’analyse de sécurité.

L’extension Snyk pour IDE est gratuite. Si vous utilisez PyCharm, recherchez Snyk dans la vue Plugins pour la télécharger directement. Avec VS Code, vous pouvez également la trouver dans la marketplace Extensions, directement depuis l’IDE.

Détectez les vulnérabilités de sécurité FastAPI dans votre IDE.

Présentation de Snyk Open Source et de ses fonctionnalités

Snyk Open Source est un outil puissant qui permet de détecter et de corriger les vulnérabilités dans les dépendances open source et les images de conteneurs. Il est conçu pour s’intégrer facilement à votre base de code et à vos systèmes CI/CD, ce qui en fait un outil pratique pour les développeurs. Il donne accès à une base de données complète de vulnérabilités connues afin de permettre aux développeurs de prévenir les failles de sécurité.

Guide étape par étape pour analyser les dépendances Python à la recherche de vulnérabilités avec Snyk

Pour analyser les dépendances Python à la recherche de vulnérabilités avec Snyk, vous devez d’abord installer Snyk CLI. Pour cela, suivez l’une des méthodes décrites dans le guide. Si vous disposez d’un environnement Node.js, vous pouvez installer rapidement Snyk avec npm install -g snyk, puis exécuter run snyk auth pour vous authentifier.

Une fois Snyk installé, utilisez la commande snyk test pour rechercher des vulnérabilités dans votre projet Python :

snyk test --all-projects

Snyk analysera alors toutes vos dépendances et les comparera à sa base de données de vulnérabilités. Si des problèmes sont détectés, Snyk générera un rapport détaillé contenant des informations sur les vulnérabilités, leur gravité et les correctifs possibles.

Surveiller vos projets avec Snyk est essentiel pour préserver la sécurité de votre application. Snyk vous permet non seulement de détecter les vulnérabilités, mais aussi d’appliquer des correctifs automatisés, ce qui vous fait gagner du temps et économiser des ressources.

Snyk propose également des alertes de vulnérabilité qui vous avertissent des nouvelles vulnérabilités susceptibles d’affecter vos projets. Vous pouvez ainsi garder une longueur d’avance et corriger les problèmes de sécurité avant qu’ils ne soient exploités.

La commande snyk monitor vous permet de créer un instantané des dépendances actuelles de votre projet et de surveiller les vulnérabilités :

snyk monitor

Comment intégrer Snyk à vos dépôts Git

En intégrant Snyk à vos dépôts Git, vous pouvez analyser automatiquement chaque commit à la recherche de vulnérabilités. Pour cela, ajoutez Snyk comme webhook dans les paramètres de votre dépôt.

Snyk s’intègre à GitHub et aux dépôts Git pour vérifier les pull requests et prévenir les vulnérabilités de sécurité dans FastAPI.

Une fois cette configuration effectuée, chaque push vers votre dépôt déclenchera une analyse Snyk, pour vous aider à détecter et à corriger les vulnérabilités le plus tôt possible.

En conclusion, Snyk Open Source est un outil précieux pour préserver la sécurité de vos projets Python. En analysant les vulnérabilités, en surveillant vos projets et en s’intégrant à vos dépôts Git, Snyk vous aide à maintenir une base de code robuste et sécurisée. Si ce n’est pas déjà fait, créez gratuitement un compte Snyk et commencez dès aujourd’hui à sécuriser vos applications.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis de capture du drapeau en regardant à la demande notre atelier virtuel d’initiation.