JeuWeb - Crée ton jeu par navigateur
Se protéger contre l'injection SQL - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Se protéger contre l'injection SQL (/showthread.php?tid=3277)

Pages : 1 2 3


RE: Se protéger contre l'injection SQL - Ekilio - 20-11-2008

Je suis en train de rédiger un tutorial sur le casting et les types. Après, ta remarque est tout à fait juste ; mais elle présente une faille, c'est que indiquer qu'un point est problématique c'est donner un indice à un éventuel pirate.

C'est un cas précis où il faut comparer la sécurité et la performance ; mais si un pirate voit qu'il y a une erreur chaque fois qu'il tente de transformer un paramètre pour que ce ne soit plus un entier, il n'aura pas la même réaction que lorsqu'il ne note pas d'erreur (chaque erreur étant un indice lorsqu'on cherche à pirater un site web).

On pourra me répondre (avec raison) que c'est pousser la paranoïa un peu loin ; je l'admet et je l'assume totalement. C'est juste que j'ai l'habitude de raisonner d'abord au terme de minimorceau de sécurité avant de raisonner en terme de performance.

Pour la différence entre intval() et (int) $variable, je cherche depuis quelques temps un benchmark sur ça, et je pense que je vais finir par le faire moi-même ; en attendant, je préfere (mais là encore c'est vraiment quelque chose de personnel) intval() que je trouve plus naturel à écrire en php que (int). D'autant plus que certains éditeurs (comme la chose infame que j'utilisait il y a quelques années) ne supportent pas (int) en php. Mais comme je le disais, c'est vraiment personnel à ce niveau-là et (int) serait tout aussi, voir plus, adapté.

Edit : Je viens de faire un benchmark, et effectivement, (int) est presque deux fois plus rapide que intval() (Pour 10000 itérations, 0.0065 seconde pour intval contre 0.0036 pour (int)). Donc effectivement, (int) est plus interessant et plus adapté.


RE: Se protéger contre l'injection SQL - Sephi-Chan - 21-11-2008

Merci beaucoup pour cette contribution, Ekilio ! J'ai déplacé ton article dans Développement > Ressources. Le lien direct vers ce dernier : Le typage en PHP.


Sephi-Chan


RE: Se protéger contre l'injection SQL - Anthor - 21-11-2008

Ekilio a écrit :Je suis en train de rédiger un tutorial sur le casting et les types. Après, ta remarque est tout à fait juste ; mais elle présente une faille, c'est que indiquer qu'un point est problématique c'est donner un indice à un éventuel pirate.

C'est un cas précis où il faut comparer la sécurité et la performance ; mais si un pirate voit qu'il y a une erreur chaque fois qu'il tente de transformer un paramètre pour que ce ne soit plus un entier, il n'aura pas la même réaction que lorsqu'il ne note pas d'erreur (chaque erreur étant un indice lorsqu'on cherche à pirater un site web).

On pourra me répondre (avec raison) que c'est pousser la paranoïa un peu loin ; je l'admet et je l'assume totalement. C'est juste que j'ai l'habitude de raisonner d'abord au terme de minimorceau de sécurité avant de raisonner en terme de performance.

Lancer une erreur ne veut pas dire l'afficher. Les classes d'exception permettent facilement d'afficher une page d'erreur tout en mailant la vraie erreur pour l'administrateur.

Parce que typer une chaine donne souvent 0, il est inutile de lancer la requête sur l'id 0. Voir même avec une chaine en typant un entier, je peux modifier un identifiant aléatoire suivant la chaine, par exemple "3 chiens" donne "3"...

En gros :
Code PHP :
<?php 
$id
= "3 petits chiens";
'SELECT * FROM table WHERE id = ' . (int) $id
Je suis piraté, le monsieur il a récup ma ligne 3.

Code PHP :
<?php 
$id
= "3 petits chiens";
'SELECT * FROM table WHERE id = ' . $id
SQL refuse la requête.

Le typage ne sert en gros a rien, si ce n'est à être propre, la vérification doit se faire en amont, SQL, typera de lui-même


RE: Se protéger contre l'injection SQL - Ekilio - 21-11-2008

Pas d'accord. Le typage sert à la sécurité, et je redonne l'exemple cité plus haut et le tien :

Code PHP :
<?php 
$id
= "0 OR 1 = 1";
'SELECT * FROM table WHERE id = ' . $id

Et là tu es piraté. Je rajouterais que le changement d'ID ne peux pas dans le cas de variable récupérées être validé aussi simplement : si tu passes une variable par URL ou par un formulaire (qui sont les deux cas où il est le plus important de typer), c'est précisément que tu veux la récupérer dans ton autre page, donc tu ne peux pas vérifier qu'elles soient bonnes. L'exemple :

Code PHP :
<?php 
$id
= "3 petits chiens";
'SELECT * FROM table WHERE id = ' . (int) $id

N'a pas pour moi de logique : effectivement, là le pirate récupère l'élément 3. Mais en même temps, que tu types ou pas, si il veux récupérer l'élément 3, il lui suffit de changer ton formulaire ou la variable récupérée, et tu n'y pourras rien... Donc le typage t'évite une énorme faille de sécurité alors que le non-typage ne t'en enlève pas.

Ekilio, vraiment perplexe sur l'exemple cité contre le typage...


RE: Se protéger contre l'injection SQL - Anthor - 21-11-2008

Je répondais à l'exemple de Sephi, la vérification doit se faire avant l'envoi de la requête. Pas sur la requête.
Le typage seul ne suffit pas.

D'ailleurs il existe de très bon plugins pour tester tout ça
http://securitycompass.com/exploitme.shtml

Code PHP :
<?php 
$id
= "0 OR 1 = 1";
'SELECT * FROM table WHERE id = ' . $id

La suite est je suppose puisque on ne demande qu'un id :
Code PHP :
<?php 
$res
= mysql_query($sql);
$data = mysql_fetch_assoc($res);
Donc au final, que ton pirate demande un ligne précise ou toute, il ne recevra que la ligne précise ou la première ligne retournée.
Dans tout les cas ton exemple ne change rien au retour du mien ^^


RE: Se protéger contre l'injection SQL - pascal - 21-11-2008

Personnellement, j'utilise un framework qui gère tout ça :
- chaque donnée posséde un validateur
- chaque donnée a une portée : peut-elle être modifiée par l'utilisateur ?
- chaque donnée est filtrée par le framework

Les frameworks ont ça de bon : permettre de se consacrer à des questions plus haut niveau (conception ...) par opposition à la réécriture systèmatique de classes techniques.

A+

Pascal


RE: Se protéger contre l'injection SQL - Ekilio - 21-11-2008

Certes, mais dans ce cas, un autre exemple des dangers du non-typage :

Code PHP :
<?php 
$id
= '0; DROP TABLE table';
'SELECT * FROM table WHERE id = ' . $id;

Et là, mine de rien tu viens de perdre toutes tes données...

Cela dit, je suis d'accord sur le fait que le typage seul ne suffit pas. Mais ça reste une mesure de sécurité très importante, à mes yeux.


RE: Se protéger contre l'injection SQL - Sephi-Chan - 21-11-2008

Désolé d'être un peu sec, mais toutes ces considération n'ont même pas lieu d'être.

Les bonnes pratiques du développement et de la sécurité veulent qu'on valide d'abord les données puis qu'on les utilises une fois qu'elles sont garanties fiables. Ça règle le problème des trous de sécurité et c'est propre.

Tout comme Pascal, j'utilise un framework (Zend Framework en ce moment) qui fait ça pour moi, je n'ai donc à coder que mon application, pas à m'occuper de ces problèmes bassement techniques qui ont déjà été vu et revus par beaucoup des gens dont c'est le métier. C'est bien plus sécurisant que de tout faire soi-même.


Sephi-Chan


RE: Se protéger contre l'injection SQL - Anthor - 21-11-2008

Ekilio a écrit :Certes, mais dans ce cas, un autre exemple des dangers du non-typage :

Code PHP :
<?php 
$id
= '0; DROP TABLE table';
'SELECT * FROM table WHERE id = ' . $id;

Et là, mine de rien tu viens de perdre toutes tes données...

Cela dit, je suis d'accord sur le fait que le typage seul ne suffit pas. Mais ça reste une mesure de sécurité très importante, à mes yeux.

Que ton utilisateur qui sélectionne puisse DROP c'est déjà un trou en soit ^^

Citation :Désolé d'être un peu sec, mais toutes ces considération n'ont même pas lieu d'être.
Les bonnes pratiques du développement et de la sécurité veulent qu'on valide d'abord les données puis qu'on les utilises une fois qu'elles sont garanties fiables. Ça règle le problème des trous de sécurité et c'est propre.

Tout à fait d'accord ^^

Sans allez forcement vers le framework, y'a tout un tas de classes qui font cela très bien. Maintenant faut arrêter, le typage ne change rien à la sécurité, dans tous les exemples donnés, c'est un pansement, à des problèmes en amont.


RE: Se protéger contre l'injection SQL - Plume - 21-11-2008

Même sans framework, tu peux pas faire ça chez moi. J'aurai -comme tout le monde ici présent- plutôt tendance à faire ça :
Code PHP :
<?php
$id
= '0; DROP TABLE table';

$intId = mysql_real_escape_string($id);
'SELECT * FROM table WHERE id = ' . $intId . ';';

Et donc, typage ou pas, j'm'en fous, ça passe pas.

P.