SQL injections en Laravel
Laravel fournit un générateur de requêtes robuste et un ORM puisant, mais malgré leur puissance, vous n'êtes pas totalement à l'abri.
Laravel fournit un générateur de requêtes robuste et un ORM éloquent. Et grâce à eux la plupart des requêtes sont protégées par défaut dans les applications Laravel, donc par exemple une requête comme :
Product::where('category_id', $request->get('category_id'))->get();
sera automatiquement protégé, car sous le capot, Laravel traduira le code en une instruction préparée et s'exécutera.
Mais les développeurs font généralement des erreurs en supposant que Laravel protège de toutes les injections SQL, alors qu'il existe certains vecteurs d'attaque que Laravel ne peut pas protéger, voici les causes les plus courantes d'injections SQL qui pouront vous surprendre.
1. Injection SQL via le nom de la colonne
La première erreur courante est que beaucoup de gens pensent que Laravel échapperait à tout paramètre passé à Query Builder ou à Eloquent. Mais en réalité, il n'est pas sûr de transmettre des noms de colonnes contrôlés par l'utilisateur au générateur de requêtes. Voici un avertissement de la documentation de Laravel.
Donc le code suivant sera vulnérable à une injection SQL
$categoryId = $request->get('category_id');
$orderBy = $request->get('orderBy');
Product::where('category_id', $categoryId)
->orderBy($orderBy)->get();
et si quelqu'un fait une demande avec la valeur de paramètre "orderBy" suivante :
http://example.com/users?orderBy=id->test"' ASC, IF((SELECT count(*) FROM users ) < 10, SLEEP(20), SLEEP(0)) DESC -- "'
sous le capot, la requête suivante sera exécutée et nous obtiendrons une injection SQL réussie.
select
* from `users`
order by `id`->'$."test"' ASC,
IF((SELECT count(*) FROM users ) < 10, SLEEP(20), SLEEP(0)) DESC
-- "'"' asc limit 26 offset 0
Il est important de mentionner que le vecteur d'attaque démontré est corrigé sur les dernières versions de Laravel, mais malgré tout, Laravel avertit les développeurs, même dans la dernière documentation, de ne pas transmettre les noms de colonnes contrôlés par l'utilisateur à Query Builder sans liste blanche.
En général, même s'il n'y a aucune possibilité de transformer une colonne personnalisée en une chaîne SQL injectée, nous ne recommandons toujours pas d'autoriser le tri des données par n'importe quel nom de colonne fourni par l'utilisateur, car cela peut introduire un problème de sécurité. Prenons un exemple lorsqu'une table « users » peut avoir une colonne secrète « secretAnswer », un attaquant intelligent pourrait éventuellement en déduire la valeur sans jamais avoir besoin d'une injection SQL.
2. Injection SQL via des règles de validation
Regardons le code de validation simplifié suivant
$id = $request->route('id');
$rules = [
'username' => 'required|unique:users,name,' . $id,
];
$validator = Validator::make($request->post(), $rules);
Étant donné que Laravel utilise $id ici pour interroger cette base de données et que $id n'est pas échappé, cela permettra à un attaquant d'effectuer une injection SQL. Vous pouvez en savoir plus sur l'accès aux injections SQL via l'injection de règles de validation ici.
3. Injection SQL via des requêtes brutes
Un autre modèle qui mérite d'être mentionné ici, mais moins courant dans nos revues de code de sécurité, consiste simplement à utiliser la fonction DB::raw à l'ancienne et à ne pas échapper aux données transmises. Un modèle comme celui-ci se produit généralement rarement, principalement dans les cas où il est nécessaire de transmettre une requête personnalisée. Si vous devez utiliser la fonction DB::raw pour une requête personnalisée, assurez-vous d'échapper aux données transmises via la méthode DB::getPdo()->quote.
Un point que je n'ai as souligné ? ajoute le en commentaire !
Voir plus
0 commentaire(s)
Posts similaires
Tutoriel Laravel 8 et Jetstream
Tutoriel Laravel 9 CRUD pour débutant : insérer, Lire, modifier et supprimer
Tutoriel : vérification des e-mails en Laravel
Laravel 9 est maintenant disponible !
Catégories
Soyez au courant des dernières tendances
Abonnez-vous pour obtenir les meilleurs articles, tutoriels, astuces et informations !
Laissez votre commentaire à @johnmbiya