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 - Zamentur - 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.

Sauf que ce trucs ne marche pas...
Car mysql_query et mysql_unbufferde_query n'execute qu'une seul requete à la fois...
Du coup çà ne s'executerait pas! Et heureusemnt parce que vu le nombre d'application qui sont sensible à ce problème!


Sinon perso, pour eviter d'oublier de proteger contre les injections, mes classes de gestion sql le font pour moi. L'avantage c'est aussi que c'est beaucoup plus agréable à l'oeil!

Code PHP :
<?php 
$db
->query("SELECT `password`,`id` FROM `member` WHERE `login`='%s'",$_POST['login']);
Ainsi $_POST['login'] sera forcément passé avec mysql_real_escape_string().


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

Plume a écrit :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.

Heu... Si, ça passe. Voir la doc : la fonction mysql_real_escape_string ne met un \ que devant quelques caractères précis : NULL, \x00, \n, \r, \, ', " et \x1a.

C'est à dire : le caractère NULL, le caractère de code ascii 0, les deux types de retours à la ligne, les \, les deux types de guillemets, et le caractère de code ascii 26, c'est à dire le retour arrière.

Cette fonction ne te protegerais donc absoluement pas dans le cas présent. Et ta table serait donc droppée ; c'est précisément dans ce genre de cas que le typage est important et que vérifier qu'on a un entier est primordial.


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

Ce qu'un lecteur non averti doit comprendre en lisant ce sujet, c'est qu'il ne doit absolument pas se fier au typage qui n'est finalement pas utile. C'est bien de savoir que ça existe (pour ça, ton article est intéressant), mais concrètement ça ne sert pas.

PHP est pauvrement typé, c'est un fait. Emuler un typage fort n'aurait strictement aucun sens.

Le débat qui est tenu ici dépasse le contexte de ce sujet et n'est pas constructif (c'est d'ailleurs pour ça que je ne le scinde pas) puisqu'on parle de choses impossible :
  • Non, le DROP ne fonctionnera pas puisque le pilote MySQL n'effectue qu'une action par requête (puis l'utilisateur n'a pas les droits) ;
  • Non le typage ne peut pas protéger efficacement de l'injection SQL (puisqu'il ne peut pas protéger les chaînes de caractères) ;

On en revient donc au sujet : Se protéger contre l'injection SQL.


Plume a écrit :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.
Beaucoup de gens (souvent les débutants mais pas uniquement) pense que mysql_real_escape_string() protège, mais il ne sert qu'à protéger les chaînes qu'on ne peut pas pas contrôler.


Sephi-Chan


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

Je sais, je sais. J'ai remarqué après coup que j'avais probablement fait une boulette. C'est le problème que je rencontre avec les frameworks, c'est que j'oublie certaines bonnes habitudes puisqu'il y pense à ma place. Dans ma librairie perso, je fais un truc comme ça pour la validation de données provenant de formulaire :
Code PHP :
<?php 
$this
->_arrValidation->setRules('username', 'Username', 'trim|addslashes|mysql_real_escape_string|required|min_length[5]|max_length[12]|xss_clean');
$this->_arrValidation->setRules('password', 'Password', 'trim|addslashes|mysql_real_escape_string|required|matches[passconf]|md5');
$this->_arrValidation->setRules('passconf', 'Password Confirmation', 'trim|addslashes|mysql_real_escape_string|required');
$this->_arrValidation->setRules('email', 'Email', 'trim|addslashes|mysql_real_escape_string|required|valid_email');
Ce système est encore à l'essai mais son principe est de mettre le nom des fonctions que je souhaite utiliser pour traiter mes données. Ces fonctions sont soit codées à mano dans le core de la librairie, soit des fonctions natives à PHP.

Donc comme vous pouvez le voir, je ne me contente pas de mysql_real_escape_string() Smile

P.


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

Je dois avouer que je vous est lâché depuis un moment Wink

Je suis qu'un petit programmeur qui a appris seul après les cours le soir...tout ça pour moi c'est du charabia, et j'en reste au même point qu'à mon 1er post en faites.

Si quelqu'un pouvait faire un petit résumé rapide, simple et efficace de tout ça (du typage etc...), se serait vraiment sympa Wink

Merci

Edit : ET ma question de départ est comment se protéger au mieux de l'injection SQL ?


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

Et bien, pour te protéger efficacement des injections, il te suffit de vérifier les données que tu vas utiliser dans ta requête.
Il faut vérifier qu'il s'agit bien de ce que tu attends.

Admettons que tu permettes à tes membres de choisir un choix dans une liste (un pays, par exemple). Dans ton script de traitement, il faut que tu vérifies si la valeur entrée est bien autorisée.

Si tu attends l'identifiant d'un membre, tu dois vérifier que c'est bien un entier positif et qu'il est bien présent dans ta base.

Si tu attends du texte arbitraire (un message de forum, par exemple), tu ne peux rien faire de plus que de l'échapper (avec mysql_real_escape_string()).

Voilà, c'est simple sur le papier, mais en pratique, le plus difficile est de penser à tout.


Sephi-Chan


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

Ok, et que viens faire le typage et le long tuto de Ekilio dans tout ça?


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

Deux choix :
  • Utilise un framework ou une librairie
  • Utilise des fonctions comme mysql_real_escape_string() addslashes() trim()

Ensuite, contrôle toujours que la donnée que tu reçois est bien du type que tu attends, appartient bien à la liste que tu as écrit,...

Bref dans tous les cas --> Toujours contrôler ce qu'on reçoit Smile

P.

[Edit] Grilled.

Kassak : Rien =)


RE: Se protéger contre l'injection SQL - Holy - 06-12-2008

(21-11-2008, 10:49 PM)Plume a écrit : Deux choix :
  • Utilise un framework ou une librairie
  • Utilise des fonctions comme mysql_real_escape_string() addslashes() trim()
Je pige pas pourquoi utiliser trim() ?

Personnellement, j'ai une bête fonction qui me permet de déterminer "ce qui doit rentrer dans la BDD.
Ça donne ça:
Code PHP :
<?php
function secure($champ, $type, $extra = FALSE) {
if(
$type == 'int') {
return
intval($_POST[$champ]);
}
elseif(
$type == 'string') {
return
mysql_real_escape_string($_POST[$champ]);
}
}
?>
(C'est schématique évidemment)

La variable $extra que je développe pas ici me permet d'ajouter éventuellement une condition spéciale sur un champ.


RE: Se protéger contre l'injection SQL - Sephi-Chan - 06-12-2008

Je ne trouve pas ça très utile… Tout au plus un gettype() pour distinguer les chaînes et les échapper, et encore…

Quitte à faire ça, autant tout faire manuellement.


Sephi-Chan