Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🐍
Intermediaire 25 min Flask

Securiser une application Flask

Sécuriser une application Flask : Un Tutoriel approfondi

Pourquoi Securiser une application Flask ?

Dans un monde où la sécurité est devenue une priorité croissante, il est crucial que les développeurs soient conscients des risques liés à l'application web Flask. Le développement d'une application Flask peut sembler simple et ludique au début, mais elle peut rapidement devenir vulnérable aux attaques si elle n'est pas correctement sécurisée.

Un cas concret de situation est lorsqu'un développeur crée un site web pour une entreprise qui gère des informations sensibles comme les données clients ou les paiements. Si ce site n'est pas sécurisé, il peut être facilement piraté et toutes ces informations compromises.

Prerequis

  • Connaissance de base en Python
  • Connaissance de la structure d'une application Flask
  • Installation de Flask : pip install flask
  • Installation de Werkzeug pour les tests : pip install werkzeug

Concepts fondamentaux

1. Authentification et Autorisation

L'authentification est le processus par lequel un utilisateur prouve son identité, tandis que l'autorisation consiste à déterminer quelles actions un utilisateur peut effectuer une fois qu'il a été authentifié.

## Importation des modules nécessaires
from flask import Flask, request, session, redirect, url_for, render_template_string
app = Flask(__name__)
app.secret_key = 'supersecretkey'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        # Vérification des identifiants (pour le but de ce tutoriel)
        if username == 'admin' and password == 'secret':
            session['user'] = username
            return redirect(url_for('home'))
        else:
            return 'Nom d\'utilisateur ou mot de passe incorrect'
    return render_template_string('''
        <form method="post">
            Username: <input type="text" name="username"><br>
            Password: <input type="password" name="password"><br>
            <input type="submit" value="Login">
        </form>
    ''')

@app.route('/home')
def home():
    if 'user' in session:
        return f'Welcome {session["user"]}!'
    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=True)

2. Protection contre les injections SQL

Les injections SQL sont une des vulnérabilités les plus courantes dans les applications web.

## Importation des modules nécessaires
from flask import Flask, request
import sqlite3

app = Flask(__name__)

@app.route('/search', methods=['GET'])
def search():
    query = request.args.get('query')
    # Injection SQL potentielle (pour le but de ce tutoriel)
    conn = sqlite3.connect('example.db')
    cursor = conn.cursor()
    cursor.execute(f"SELECT * FROM users WHERE name LIKE '%{query}%'")
    results = cursor.fetchall()
    conn.close()
    return str(results)

if __name__ == '__main__':
    app.run(debug=True)

3. Protection contre les cross-site scripting (XSS)

Les attaques XSS se produisent lorsque le code HTML ou JavaScript est injecté dans une page web que l'utilisateur peut ensuite exécuter.

## Importation des modules nécessaires
from flask import Flask, request, escape

app = Flask(__name__)

@app.route('/greet', methods=['GET'])
def greet():
    name = request.args.get('name')
    # Injection XSS potentiel (pour le but de ce tutoriel)
    return f'<h1>Hello {name}</h1>'

if __name__ == '__main__':
    app.run(debug=True)

4. Protection contre les attaques CSRF

Les attaques CSRF se produisent lorsque l'utilisateur est trompé en cliquant sur un lien malveillant qui envoie une requête non autorisée à une application.

## Importation des modules nécessaires
from flask import Flask, request, session, redirect, url_for, render_template_string
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
app.secret_key = 'supersecretkey'
csrf = CSRFProtect(app)

@app.route('/transfer', methods=['GET'])
def transfer():
    return render_template_string('''
        <form method="post" action="/process_transfer">
            Amount: <input type="text" name="amount"><br>
            Destination: <input type="text" name="destination"><br>
            <input type="submit" value="Transfer">
        </form>
    ''')

@app.route('/process_transfer', methods=['POST'])
def process_transfer():
    amount = request.form['amount']
    destination = request.form['destination']
    # Traitement du transfert (pour le but de ce tutoriel)
    return f'Transfer of {amount} to {destination} processed.'

if __name__ == '__main__':
    app.run(debug=True)

Mise en pratique : Projet fil rouge

Mini-Projet : Gestionnaire de Tâches

Ce projet implémentera un simple gestionnaire de tâches avec des fonctionnalités de connexion, d'ajout et de suppression de tâches.

## Importation des modules nécessaires
from flask import Flask, request, render_template_string, session, redirect, url_for
app = Flask(__name__)
app.secret_key = 'supersecretkey'

tasks = []

@app.route('/')
def index():
    return render_template_string('''
        <h1>Gestionnaire de Tâches</h1>
        <a href="/login">Login</a> | <a href="/register">Register</a>
        {% if session.get("user") %}
            <a href="/logout">Logout</a>
            <ul>
                {% for task in tasks %}
                    <li>task</li>
                {% endfor %}
            </ul>
            <form method="post" action="/add_task">
                Task: <input type="text" name="task"><br>
                <input type="submit" value="Add Task">
            </form>
        {% endif %}
    ''')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        # Vérification des identifiants (pour le but de ce tutoriel)
        if username == 'admin' and password == 'secret':
            session['user'] = username
            return redirect(url_for('index'))
        else:
            return 'Nom d\'utilisateur ou mot de passe incorrect'
    return render_template_string('''
        <form method="post">
            Username: <input type="text" name="username"><br>
            Password: <input type="password" name="password"><br>
            <input type="submit" value="Login">
        </form>
    ''')

@app.route('/logout')
def logout():
    session.pop('user', None)
    return redirect(url_for('index'))

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        # Enregistrement des utilisateurs (pour le but de ce tutoriel)
        session['user'] = username
        return redirect(url_for('index'))
    return render_template_string('''
        <form method="post">
            Username: <input type="text" name="username"><br>
            Password: <input type="password" name="password"><br>
            <input type="submit" value="Register">
        </form>
    ''')

@app.route('/add_task', methods=['POST'])
def add_task():
    task = request.form['task']
    tasks.append(task)
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)

Erreurs frequentes et debugging

1. Injection SQL

## ❌ Mauvais
def get_user(username):
    conn = sqlite3.connect('example.db')
    cursor = conn.cursor()
    cursor.execute(f"SELECT * FROM users WHERE username = '{username}'")
    user = cursor.fetchone()
    conn.close()
    return user

## ✅ Correct
from flask_sqlalchemy import SQLAlchemy

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)

def get_user(username):
    user = User.query.filter_by(username=username).first()
    return user

2. XSS

## ❌ Mauvais
def greet(name):
    return f'<h1>Hello {name}</h1>'

## ✅ Correct
from flask import escape

def greet(name):
    return f'<h1>Hello {escape(name)}</h1>'

3. CSRF

## ❌ Mauvais
@app.route('/transfer', methods=['GET'])
def transfer():
    return render_template_string('''
        <form method="post" action="/process_transfer">
            Amount: <input type="text" name="amount"><br>
            Destination: <input type="text" name="destination"><br>
            <input type="submit" value="Transfer">
        </form>
    ''')

## ✅ Correct
@app.route('/transfer', methods=['GET'])
def transfer():
    return render_template_string('''
        <form method="post" action="/process_transfer">
            Amount: <input type="text" name="amount"><br>
            Destination: <input type="text" name="destination"><br>
            CSRF Token: <input type="hidden" name="csrf_token" value="csrf_token()">
            <input type="submit" value="Transfer">
        </form>
    ''')

Pour aller plus loin

1. Utilisation de Flask-HTTPAuth pour l'authentification

Flask-HTTPAuth est une extension qui facilite l'ajout d'authentification HTTP à des applications Flask.

Documentation Flask-HTTPAuth

2. Utilisation de Flask-Security pour la gestion de l'utilisateur

Flask-Security offre des fonctionnalités comme le register, login, logout et mot de passe oublié.

Documentation Flask-Security

3. Sécurité de la communication HTTPS

Utilisez HTTPS pour sécuriser la communication entre le client et le serveur.

Tutoriel sur HTTPS avec Flask

Défi pratique : Sécurisation d'une API RESTful

Implémentez une API RESTful sécurisée avec Flask, incluant l'authentification JWT et la protection contre les attaques CSRF.

Tuto sur API sécurisée avec Flask


Ce tutoriel a couvert de nombreux aspects importants de la sécurité d'une application Flask. En suivant ces concepts et en appliquant les bonnes pratiques, vous pouvez construire des applications web sécurisées pour protéger vos utilisateurs et leurs données sensibles.

Besoin d'aide sur Flask ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment configurer une application Flask pour éviter les injections SQL ?
Pour éviter les injections SQL dans votre application Flask, utilisez des requêtes paramétrées et validez toujours les entrées utilisateur.
Quelles sont les meilleures pratiques pour sécuriser le stockage des mots de passe utilisateurs ?
Stockez les mots de passe en hashant avec un algorithme fort comme bcrypt. Utilisez également une salte unique pour chaque mot de passe.
Comment protéger ma application contre les attaques CSRF ?
Utilisez la protection CSRF intégrée de Flask-WTF en ajoutant le champ CSRFProtection à vos formulaires. Assurez-vous également que toutes les requêtes POST et PUT sont sécurisées.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.