FlawOpen

flawopen.com/SQL Injection en Ruby/ActiveRecord where()

L’interpolation dans where() de Rails est-elle sûre ?

Page de référence
Réponse courte

Imaginez SQL comme un formulaire avec des consignes fixes et des cases réservées aux valeurs. Un paramètre lié remplit une case ; l’interpolation Ruby insère le texte de la requête dans les consignes avant que Rails puisse distinguer les deux. Gardez la structure SQL fixe et transmettez les valeurs non fiables comme paramètres.

UNSAFE
User.where(
  "id = #{params[:id]}"
)
SAFE
User.where(id: params[:id])
# or, for more complex conditions:
User.where("id = ?", params[:id])

Pourquoi l’interpolation modifie la requête

Ruby évalue #{...} avant qu’Active Record reçoive la condition. Par exemple, where("id = #{params[:id]}") fournit à Rails une chaîne SQL déjà assemblée ; l’entrée de la requête peut alors modifier le prédicat. Active Record documente cette construction de chaîne comme dangereuse. Utilisez un hash pour les conditions prises en charge (égalité, intervalle ou sous-ensemble), ou des marqueurs ? pour les autres prédicats. Les marqueurs lient des valeurs, pas des identifiants ni des mots-clés SQL ; gardez la structure fixe ou choisissez les identifiants dans une liste d’autorisation stricte.

Vérifier votre code

rg -n 'where\s*\(' app/
Examinez les résultats pour repérer les données de requête interpolées ou concaténées dans les chaînes de condition. Brakeman signale les risques de SQL Injection lorsque son analyse détecte un flux de données dangereux ; un résultat sans alerte ne prouve pas que toutes les requêtes sont sûres.

Questions fréquentes

Puis-je utiliser des conditions hash pour toutes les requêtes ?

Non. Les conditions hash de Rails prennent en charge l’égalité, les intervalles et les sous-ensembles (IN). Pour les autres prédicats, utilisez une condition SQL fixe avec des valeurs liées, par exemple where("price > ?", amount). Le binding protège les valeurs, pas les noms dynamiques de tables ou de colonnes ni les fragments SQL.

Références

À voir aussi Injection SQL (CWE-89) : fonctionnement et prévention dans chaque langage — flawopen.com Sequelize query() protège-t-il contre les injections SQL ? SQLAlchemy text() protège-t-il contre les injections SQL ? La vérification des requêtes sqlx à la compilation empêche-t-elle les injections SQL ? Les procédures stockées empêchent-elles l’injection SQL ? TypeORM QueryBuilder protège-t-il des injections SQL ? Django ORM et SQL Injection : bonnes pratiques