0Pricing
Python Academy · Leçon

Requêtes paramétrées

Prévenir les injections SQL

Requêtes paramétrées est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Python Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Python Academy comprend 4 leçons au total.

Le danger de la concaténation de chaînes

Construire du SQL en concaténant des chaînes est risqué. Si l'entrée de l'utilisateur contient du SQL, elle peut modifier votre requête. C'est ce qu'on appelle une injection SQL.

Ne faites jamais cela avec des données non fiables.

name = 'Alice'
# Unsafe pattern - do NOT do this
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)

À quoi ressemble une injection

Imaginez une valeur malveillante. Sa concaténation modifie complètement le sens de la requête.

name = "x' OR '1'='1"
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)
print('The OR clause makes every row match!')

Les espaces réservés à la rescousse

La méthode sûre consiste à utiliser des requêtes paramétrées. Utilisez ? comme espace réservé et transmettez les valeurs sous forme de tuple. Le pilote les échappe de manière sûre.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Plusieurs espaces réservés

Utilisez un ? par valeur. Transmettez-les dans un tuple, dans le même ordre que celui de leur apparition.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Tuples à valeur unique

Un tuple à un seul élément nécessite une virgule finale : ('Alice',). Sans cette virgule, Python considère les parenthèses comme de simples parenthèses de groupement.

good = ('Alice',)
bad = ('Alice')
print(type(good), type(bad))

Tentative d'injection bloquée

Avec des espaces réservés, une valeur malveillante est traitée comme une simple donnée et non comme du SQL. Elle ne correspond simplement à rien.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
evil = "x' OR '1'='1"
cur.execute('SELECT * FROM users WHERE name = ?', (evil,))
print('Rows matched:', cur.fetchall())
conn.close()

Espaces réservés nommés

SQLite prend également en charge les espaces réservés nommés avec la syntaxe :name. Transmettez un dictionnaire de valeurs.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (:n, :a)', {'n': 'Carol', 'a': 40})
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Paramètres dans WHERE

Les espaces réservés fonctionnent dans toute clause qui accepte une valeur, notamment WHERE.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Alice', 30))
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT name FROM users WHERE age > ?', (28,))
print(cur.fetchall())
conn.close()

executemany

Pour insérer de nombreuses lignes, utilisez executemany() avec une liste de tuples. Cette méthode est plus rapide et reste sûre.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
rows = [('Alice',), ('Bob',), ('Carol',)]
cur.executemany('INSERT INTO users (name) VALUES (?)', rows)
cur.execute('SELECT COUNT(*) FROM users')
print(cur.fetchone())
conn.close()

Les espaces réservés ne remplacent pas les identifiants

Les espaces réservés fonctionnent uniquement pour les valeurs, pas pour les noms de tables ou de colonnes. Ceux-ci doivent provenir d'une liste d'autorisation fiable définie dans votre propre code.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
allowed = {'name', 'id'}
col = 'name'
if col in allowed:
    cur.execute('SELECT ' + col + ' FROM users')
    print('Safe column query ran')
conn.close()

Une fonction d'insertion réutilisable

Regrouper les insertions paramétrées dans une fonction permet de garder un code propre et systématiquement sûr.

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')

def add_user(cursor, name):
    cursor.execute('INSERT INTO users (name) VALUES (?)', (name,))

add_user(cur, 'Dave')
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

Vérification rapide

Vérifiez vos connaissances sur les requêtes sûres.

Récapitulatif

Vous avez appris à écrire des requêtes protégées contre les injections.

  • Ne concaténez jamais une entrée non fiable avec du SQL
  • Utilisez des espaces réservés ? avec un tuple de valeurs
  • Les espaces réservés nommés :name acceptent un dictionnaire
  • executemany() insère de nombreuses lignes en toute sécurité
  • Les espaces réservés servent aux valeurs, pas aux identifiants

Questions Fréquemment Posées

La leçon « Requêtes paramétrées » est-elle gratuite ?

Oui — le texte complet de « Requêtes paramétrées » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Python Academy, passe à CoddyKit PRO. Le cours Python Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Requêtes paramétrées » ?

Prévenir les injections SQL Tu pratiques Python Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Python Academy ?

Aucune expérience préalable n'est requise. Python Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Requêtes paramétrées » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Python Academy ?

Oui. Chaque leçon Python Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Connexion et création de tables
  2. Insert, Select, Update, Delete
  3. Requêtes paramétrées
  4. Transactions et gestionnaires de contexte
← Retour à Python Academy