Sécurité (Flask)

La sécurité dans Flask regroupe l’ensemble des mesures et bonnes pratiques visant à protéger une application web contre les attaques, les accès non autorisés et les fuites de données.
Comme Flask est un framework minimaliste, il ne fournit pas toutes les protections par défaut, ce qui impose au développeur d’intégrer manuellement ou via des extensions les fonctionnalités de sécurité nécessaires.

Cela inclut :


Comment ça fonctionne dans Flask

Authentification et autorisation

Protection contre les attaques courantes

Sécurisation des communications

Gestion des erreurs et des logs


Exemple conceptuel


Bonnes pratiques


Pourquoi c’est important


En résumé

Fonctions :

  • Sécurité avec Flask

    Exemple de code :

    from flask import Flask, request, session, redirect, url_for, jsonify
    from werkzeug.security import generate_password_hash, check_password_hash
    
    app = Flask(__name__)
    
    # Clé secrète pour sécuriser les sessions (à garder privée !)
    app.secret_key = "une_cle_secrete_tres_complexe"
    
    # Simulation d'une "base de données" utilisateur
    users_db = {
        "alice": generate_password_hash("motdepasse123"),
        "bob": generate_password_hash("azerty")
    }
    
    # Route d'accueil
    @app.route("/")
    def home():
        if "username" in session:
            return f"Bienvenue {session['username']} ! <br><a href='/logout'>Se déconnecter</a>"
        return "Bienvenue sur le site ! <br><a href='/login'>Se connecter</a>"
    
    # Route de connexion
    @app.route("/login", methods=["GET", "POST"])
    def login():
        if request.method == "POST":
            username = request.form.get("username")
            password = request.form.get("password")
    
            if username in users_db and check_password_hash(users_db[username], password):
                session["username"] = username
                return redirect(url_for("home"))
            else:
                return "Identifiants invalides !", 401
        
        return '''
            <form method="post">
                Nom d'utilisateur : <input type="text" name="username"><br>
                Mot de passe : <input type="password" name="password"><br>
                <input type="submit" value="Se connecter">
            </form>
        '''
    
    # Route protégée (accessible uniquement aux utilisateurs connectés)
    @app.route("/secret")
    def secret():
        if "username" not in session:
            return redirect(url_for("login"))
        return jsonify({"message": f"Voici le contenu secret réservé à {session['username']} !"})
    
    # Route de déconnexion
    @app.route("/logout")
    def logout():
        session.pop("username", None)
        return redirect(url_for("home"))
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    Explication du code :

    from flask import Flask, request, session, redirect, url_for, jsonify importe les modules Flask nécessaires : Flask pour créer l’application, request pour accéder aux données envoyées par l’utilisateur, session pour gérer les sessions sécurisées, redirect et url_for pour les redirections, et jsonify pour retourner des réponses JSON.

    from werkzeug.security import generate_password_hash, check_password_hash importe des fonctions pour sécuriser les mots de passe : - generate_password_hash pour créer un hash sécurisé d’un mot de passe. - check_password_hash pour vérifier si un mot de passe correspond au hash stocké.

    app = Flask(__name__) crée une instance de l’application Flask.

    app.secret_key = "une_cle_secrete_tres_complexe" définit une clé secrète utilisée par Flask pour sécuriser les sessions et les cookies. Cette clé doit rester confidentielle.

    1️⃣ Simulation d’une "base de données" utilisateur

    users_db = { "alice": generate_password_hash("motdepasse123"), "bob": generate_password_hash("azerty") } crée un dictionnaire simulant une base de données d’utilisateurs, avec les mots de passe stockés sous forme de hash sécurisé.

    2️⃣ Route d’accueil

    @app.route("/") définit la route principale.
    La fonction home() vérifie si un utilisateur est connecté ("username" in session) : - Si oui → affiche un message de bienvenue et un lien pour se déconnecter. - Si non → affiche un lien pour se connecter.

    3️⃣ Route de connexion

    @app.route("/login", methods=["GET", "POST"]) définit une route qui accepte les méthodes GET et POST pour gérer le formulaire de connexion.

    • Si la méthode est POST : on récupère username et password envoyés par le formulaire.
    • On vérifie si l’utilisateur existe dans users_db et si le mot de passe correspond au hash stocké (check_password_hash).
    • Si la vérification réussit → on stocke le nom d’utilisateur dans session["username"] et on redirige vers home().
    • Si la vérification échoue → on renvoie un message d’erreur avec le code HTTP 401 (Unauthorized).
    • Si la méthode est GET → on retourne un formulaire HTML simple pour saisir le nom d’utilisateur et le mot de passe.
    4️⃣ Route protégée

    @app.route("/secret") définit une route accessible uniquement aux utilisateurs connectés.
    La fonction secret() vérifie si "username" est présent dans session : - Si non → redirection vers la page de connexion. - Si oui → renvoie un message JSON contenant le contenu secret pour l’utilisateur connecté.

    5️⃣ Route de déconnexion

    @app.route("/logout") définit une route pour se déconnecter.
    La fonction logout() supprime la clé "username" de la session avec session.pop("username", None) et redirige vers la page d’accueil.

    6️⃣ Lancer l’application Flask

    if __name__ == "__main__": vérifie que le fichier est exécuté directement.
    app.run(debug=True) démarre le serveur Flask en mode debug, accessible par défaut sur http://127.0.0.1:5000/. Le mode debug permet le rechargement automatique et l’affichage détaillé des erreurs.