SQL injections en Laravel - Letecode

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.

Jean Claude Mbiya
Jean Claude Mise à jour : 21 décembre 2022 1671

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.

laravel sql injection

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 !

1
Jean Claude Mbiya
Jean Claude Mbiya

Développeur Web full stack, Développeur Android (Certifié Google AAD) Formateur dans les domaines du numérique, Créateur letecode.com 👨‍💻. Je suis un grand passionné des nouvelles technologies et j'adore partager ce que j'apprend.

0 commentaire(s)

Laissez votre commentaire à @johnmbiya

ou pour laisser un commentaire