Skip to main content

Repérer et corriger les références directes non sécurisées à des objets en Python

Écrit par

Keshav Malik

feature python linting

19 juillet 2023

0 minutes de lecture

Une référence directe non sécurisée à un objet (IDOR) est une vulnérabilité de sécurité qui survient lorsque l’implémentation d’un système permet à des attaquants d’accéder directement à des objets ou ressources sensibles et de les manipuler sans vérification des autorisations. Par exemple, une IDOR peut se produire lorsqu’une application donne un accès direct à des objets à partir de données fournies par l’utilisateur, permettant ainsi à un attaquant de contourner les contrôles d’autorisation.

Comprendre les vulnérabilités IDOR

Nous devons lutter contre les IDOR pour préserver la confidentialité, l’intégrité et la disponibilité des données sensibles traitées par vos applications Python. Les développeurs doivent comprendre les vulnérabilités IDOR afin d’empêcher les accès non autorisés, de préserver la confiance des utilisateurs et d’éviter de lourdes conséquences financières et juridiques. 

Types d’IDOR

Les IDOR prennent différentes formes selon l’implémentation et les fonctionnalités de l’application.

IDOR portant sur des objets

Cette forme d’IDOR survient lorsqu’un attaquant peut accéder à un objet non autorisé ou le modifier. Un exemple courant est celui d’une application Web qui donne accès à des données sensibles, comme des comptes bancaires, au moyen d’une simple requête telle que example.com/accounts?id={account_id}. Si l’application ne vérifie pas efficacement les autorisations de la personne qui en fait la demande, des utilisateurs non autorisés peuvent consulter ou manipuler les informations des comptes.

IDOR portant sur des fichiers

Ce type d’IDOR consiste à récupérer des fichiers sans autorisation. Par exemple, si une application de messagerie stocke les journaux de conversations confidentielles dans des fichiers numérotés de façon séquentielle, un attaquant pourrait accéder à des conversations privées en envoyant des requêtes avec des numéros similaires — example.com/1.log, example.com/2.log, et ainsi de suite.

IDOR aveugle

Une IDOR aveugle désigne les cas où l’exploitation n’est pas directement visible dans la réponse du serveur, même si une modification non autorisée a pu avoir lieu. Avec une IDOR aveugle, un attaquant peut modifier les données privées d’un autre utilisateur sans les consulter. Par exemple, si une application Web permet à un utilisateur de modifier les paramètres de son profil au moyen d’un appel d’API tel que example.com/users/update?id={user_id}, un attaquant pourrait manipuler la valeur de user_id dans la requête et modifier les paramètres du profil d’un utilisateur sans consulter directement ses données.

Schémas courants pour repérer les vulnérabilités IDOR dans le code

Pour détecter les vulnérabilités IDOR dans le code, il faut rester vigilant et connaître les schémas courants :

  • Absence de contrôle d’accès : une application qui utilise les données fournies par l’utilisateur pour accéder directement à des ressources sans vérifier ses autorisations présente probablement une vulnérabilité IDOR.

  • Identifiants faciles à deviner : les identifiants faciles à deviner, tels que des entiers séquentiels (user_id=99001) ou des chaînes courtes (user_id=user1), augmentent le risque de vulnérabilités IDOR dans une application. L’utilisation d’identifiants difficiles à deviner, comme les identifiants uniques universels (UUIDs), peut réduire ce risque.

  • Accès direct aux fichiers : une application qui permet aux utilisateurs d’accéder directement à des ressources, comme des images ou des fichiers CSV, au moyen d’URL ou de paramètres de requête, est vulnérable aux IDOR. Il faut mettre en place des mécanismes de contrôle adaptés pour éviter de donner aux utilisateurs un accès direct aux fichiers.

Créer une application Python vulnérable aux IDOR avec FastAPI

Dans cette section, nous allons créer une API Web vulnérable aux IDOR avec le framework Python FastAPI. Nous verrons ensuite comment corriger cette vulnérabilité.

Pour suivre ce tutoriel pratique, vérifiez que Python 3.x est installé sur votre machine.

Pour commencer

Commençons par créer une nouvelle application. Créez un répertoire pour votre projet, puis accédez-y :

mkdir fastapi-app; cd fastapi-app

Installez ensuite FastAPI, Uvicorn, SQLAlchemy et SQLite à l’aide de la commande suivante :

pip install fastapi uvicorn sqlalchemy

Enfin, créez un fichier nommé main.py dans le répertoire du projet.

Créer une API vulnérable avec FastAPI

Maintenant que la structure des répertoires et les dépendances sont en place, écrivons le code contenant une vulnérabilité IDOR. Commencez par copier le code ci-dessous dans main.py :

from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session

app = FastAPI()

# SQLite database configuration
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

# User model
class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    uuid = Column(String, unique=True, index=True)
    username = Column(String, unique=True, index=True)
    email = Column(String, unique=True, index=True)

Base.metadata.create_all(bind=engine)

# Dependency for database session
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users/{user_id}")
async def get_user_by_id(user_id: int, db: Session = Depends(get_db)):
    user = db.query(User).filter(User.id == user_id).first()
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

La vulnérabilité IDOR se trouve dans le point de terminaison /users/user_id. Comme l’application ne comporte aucun contrôle d’accès, n’importe quel utilisateur peut consulter les données d’autres utilisateurs en modifiant user_id dans l’URL.

Repérer et corriger les vulnérabilités IDOR

Voyons maintenant comment repérer et corriger la faille de sécurité IDOR dans notre application FastAPI.

Repérer les vulnérabilités

Pour repérer les vulnérabilités IDOR, il faut rechercher des schémas précis dans le code. Dans l’application FastAPI, examinons le point de terminaison /users/{user_id}, qui présente un risque potentiel d’IDOR pour les raisons suivantes :

  • Références directes à des objets non protégées : dans la fonction get_user_by_id, le paramètre user_id fait directement référence à l’objet User dans la base de données. N’importe quel client peut manipuler la valeur de user_id dans la requête pour accéder aux données d’autres utilisateurs, car aucun mécanisme de contrôle d’accès ne protège cette référence directe.

  • Absence d’autorisation : dans cette même fonction get_user_by_id, aucune vérification ne permet de confirmer que l’utilisateur à l’origine de la requête est autorisé à accéder aux données demandées. N’importe quel utilisateur peut accéder aux données d’un autre utilisateur en manipulant le paramètre user_id.

Corriger le code vulnérable

Pour corriger la vulnérabilité IDOR, nous devons mettre à jour le point de terminaison /users/{user_id} et y ajouter des contrôles d’accès appropriés. 

Simulons un utilisateur authentifié et autorisons l’accès uniquement si la valeur user_id dans l’URL correspond à l’ID de l’utilisateur authentifié. Pour cet exemple, supposons que l’ID de l’utilisateur authentifié est 1. Voici le code mis à jour :

@app.get("/users/{user_id}")
async def get_secure_user(user_id: int, db: Session = Depends(get_db)):
    # Assume user authentication and authorization are performed here
    authenticated_user_id = "hbecec-edeek-wxwexe-cdcece" # better to use UUIDs

    if authenticated_user_id != user_id:
        raise HTTPException(status_code=403, detail="Not authorized to access this user")

    user = db.query(User).filter(User.id == user_id).first()
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

Dans ce bloc de code, nous avons ajouté un contrôle d’accès qui compare la valeur de user_id dans l’URL à authenticated_user_id. Si les identifiants ne correspondent pas, l’application renvoie une erreur HTTP 403 Forbidden. Cette erreur empêche les utilisateurs non autorisés d’accéder aux informations d’autres utilisateurs et corrige ainsi la vulnérabilité IDOR.

Détecter et corriger les problèmes de sécurité avec Snyk

Snyk est une solution de sécurité qui offre des fonctionnalités d’analyse de la composition logicielle (SCA) et de test statique de la sécurité des applications (SAST). Voyons comment utiliser Snyk pour repérer et corriger les problèmes de sécurité dans notre application FastAPI. 

Installer et authentifier Snyk CLI

Pour commencer, installez Snyk CLI sur votre machine en suivant le guide d’installation de la documentation.

Après avoir installé la CLI, vous devez authentifier votre compte Snyk. Exécutez la commande snyk auth dans le terminal. Une fenêtre de navigateur s’ouvrira et vous pourrez vous connecter avec votre compte GitHub ou Google.

Analyser les dépendances à la recherche de vulnérabilités

Pour analyser le projet à la recherche de vulnérabilités dans les bibliothèques tierces, nous avons besoin d’un fichier requirements.txt. Créez le fichier requirements.txt avec la commande suivante :

pip freeze > requirements.txt

Analysez ensuite les dépendances de votre projet à la recherche de vulnérabilités en exécutant la commande suivante dans le terminal :

snyk test --file=requirements.txt --skip-unresolved

Cette commande analyse vos dépendances, puis détecte et décrit les vulnérabilités, en précisant leur niveau de gravité et en proposant des recommandations pour les corriger. Par exemple, vous pourriez découvrir une vulnérabilité de gravité moyenne de déni de service (DoS) dans starlette@0.14.2.

Remarque : Snyk ne peut pas analyser le projet si un package requis est manquant. L’option –skip-unresolved permet de contourner ce comportement.

Corriger les vulnérabilités avec Snyk

Snyk peut également vous aider à corriger les vulnérabilités. La commande snyk fix peut résoudre automatiquement certains problèmes détectés. Snyk met à niveau ou applique des correctifs aux dépendances concernées pour les rendre sécurisées, et ainsi maintenir vos applications à jour et protégées.

Utiliser Snyk Code pour l’analyse statique du code

Snyk propose également une puissante solution de test statique de la sécurité des applications (SAST). La commande snyk code analyse le code de votre application, détecte les problèmes de sécurité et fournit des informations détaillées sur la façon de les corriger.

Pour utiliser snyk code, exécutez la commande suivante dans votre terminal :

snyk code test

Snyk Code analyse votre code en profondeur et met en évidence les éventuelles vulnérabilités de sécurité. Il propose également des conseils pour les corriger, afin de vous aider à maintenir une application sécurisée et fiable.

Les vulnérabilités IDOR expliquées

En tant que développeurs, nous devons veiller à la sécurité de nos applications. Les IDOR représentent une menace pour les applications Web : il est donc essentiel d’apprendre à les repérer et à les corriger. En comprenant bien les vulnérabilités IDOR, vous pouvez créer des applications Python à la fois performantes et sécurisées. 

Dans ce tutoriel, vous avez appris à repérer et à corriger les vulnérabilités IDOR dans une application Python. Nous avons également vu comment Snyk peut vous aider à détecter et à éliminer les risques de sécurité dans les dépendances de votre projet et dans le code de l’application. Snyk est un puissant outil de sécurité qui, intégré à votre routine de développement, ajoute une couche de protection pour renforcer votre code.

Découvrez les coulisses de Snyk avec un essai gratuit.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.