flawopen.com/SQL Injection en Ruby/ActiveRecord where()
L’interpolation dans where() de Rails est-elle sûre ?
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.
User.where(
"id = #{params[:id]}"
)
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/Questions fréquentes
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.