protection contre les injection

sami123
Invité n'ayant pas de compte PHPfrance

08 oct. 2009, 01:06

salut,

si je fait sa ,

Code : Tout sélectionner

$email =$_POST['email']; $password = $_POST['pw']; $sql = 'SELECT COUNT(`email`) FROM membres WHERE email = "'.mysql_real_escape_string($email).'" AND password = "'.mysql_real_escape_string($password).'" LIMIT 1';
sa exclu toute possibilité d'injection sql ?
et si ma variable été un entié je met mysql_real_escape_string aussi ?
merci beaucoup

Mammouth du PHP | 985 Messages

08 oct. 2009, 02:31

Avant tout, à mon avis, il faut toujours prendre comme habitude de filtrer les données.
Exemple stricte:
//fonction filtre_email par Dr@ke =)
function filtre_email($email) {
        $valid_array = array(chr(10), chr(13));
        $email = str_replace($valid_array, '', $email);
        if (filter_var($email, FILTER_VALIDATE_EMAIL) && strlen($email) < 50)  {
             return true;
        }
        else {
             return false;
        }
}

// fonction filtre_strict par Dr@ke
function filtre_strict($string) {
        if (ctype_alnum($string) && strlen($string) < 50) {
            return true;
        }
        else {
            return false;
        }
}

$email = (isset($_POST['email'])) ? trim($_POST['email']) : null;
$password = (isset($_POST['pw'])) ? trim($_POST['pw']) : null;

if (filtre_email($email) && filtre_strict($password)) {
    $sql = 'SELECT COUNT(`email`) FROM membres WHERE email = "'.mysql_real_escape_string($email).'" AND password = "'.mysql_real_escape_string($password).'" LIMIT 1';
}
else {
echo 'Erreur';
}
J'ai mis 50 caractères pour être large, cela peut-être personnalisé aussi.
La fonction filtre_email() peut-être utilisée dans tous les situations possibles (pour les emails) :wink:

C'est juste un exemple de filtrage de données stricte et sécurisé, je n'ai pas regardé ta requête, mais de cette façon tu sais au moins ce qui peut-être envoyé ou pas dans ta base de données, quelque-soit la faille possible ensuite dans ta requête.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
AB
ViPHP | 5818 Messages

08 oct. 2009, 02:43

salut,

si je fait sa ,

Code : Tout sélectionner

$email =$_POST['email']; $password = $_POST['pw']; $sql = 'SELECT COUNT(`email`) FROM membres WHERE email = "'.mysql_real_escape_string($email).'" AND password = "'.mysql_real_escape_string($password).'" LIMIT 1';
sa exclu toute possibilité d'injection sql ?
et si ma variable été un entié je met mysql_real_escape_string aussi ?
merci beaucoup
Sur le principe c'est 0k.

Et tu peux utiliser également mysql_real_escape_string() sur un entier bien qu'en théorie tu n'en aurais pas besoin. Mais en pratique, au cas où l'utilisateur rentrerait autre chose qu'un entier, etc.
Donc puisque cela ne dérange pas, autant prendre l'habitude de toujours utiliser mysql_real_escape_string()

Cela dit on utilise habituellement des doubles quotes pour entourer la requête ce qui permet de mettre les variables concaténées entre simple quote :
$sql = "SELECT COUNT(`email`) FROM membres WHERE email = '".mysql_real_escape_string($email)."' AND password = '".mysql_real_escape_string($password)."' LIMIT 1";
Sinon comme je vois que tu es dans un script d'authentification dans un espace membre, en cas de besoin il y a un tuto complet ici

ViPHP
AB
ViPHP | 5818 Messages

08 oct. 2009, 03:41

Avant tout, à mon avis, il faut toujours prendre comme habitude de filtrer les données.
Exemple stricte:
//fonction filtre_email par Dr@ke =)
function filtre_email($email) {
        $valid_array = array(chr(10), chr(13));
        $email = str_replace($valid_array, '', $email);
        if (filter_var($email, FILTER_VALIDATE_EMAIL) && strlen($email) < 50)  {
             return true;
        }
        else {
             return false;
        }
}

// fonction filtre_strict par Dr@ke
function filtre_strict($string) {
        if (ctype_alnum($string) && strlen($string) < 50) {
            return true;
        }
        else {
            return false;
        }
}

$email = (isset($_POST['email'])) ? trim($_POST['email']) : null;
$password = (isset($_POST['pw'])) ? trim($_POST['pw']) : null;

if (filtre_email($email) && filtre_strict($password)) {
    $sql = 'SELECT COUNT(`email`) FROM membres WHERE email = "'.mysql_real_escape_string($email).'" AND password = "'.mysql_real_escape_string($password).'" LIMIT 1';
}
else {
echo 'Erreur';
}
Pour ta fonction "filtre_email", les deux premières lignes ne servent à rien dans ce contexte. Pas plus que "strlen($email) < 50".
Cela dit, même si c'est inutile, cela ne devrait pas gêner sauf s'il est possible d'avoir des mails de plus de 50 caractères.

De toutes façons, si l'email envoyé - et quelque soit ce que l'utilisateur rentre puisque la fonction mysql_real_escape_string protège des injections (remarques qu'elle ajoute des slashes devant les caractères\n, \r) - ne correspond pas au champ email de sa table de donnée, la requête retournera 0.

Par contre ta fonction "filtre_strict" qui ne laisse passer que les valeurs alphanumériques avec ctype_alnum, est particulièrement mal choisie pour filtrer un mot de passe puisque cela interdit aux visiteurs d'utiliser des caractères autres.
Or un petit tour sur les forum parlant de sécurité t'indiquera qu'un mot de passe est d'autant plus sécurisé qu'il comporte des caractères spéciaux en plus de caractères alphanumériques. En fait il s'agit d'utiliser le plus vaste choix de caractères possibles ce qui rend le mdp beaucoup plus difficile à déchiffrer y compris par force brute.

Encore une fois, évites de faire des contrôles qui ne servent à rien, surtout ceux qui vont limiter les possibilités de choix des visiteurs inutilement - et qui plus est dans ce cas pour le mot de passe, au détriment de la sécurité réelle :wink:

Mammouth du PHP | 985 Messages

08 oct. 2009, 04:02

T'es drôle avec tes vérifications qui servent a rien :wink:

1) j'ai dis que c'était un exemple de filtrage de données stricte

2) j'ai dis que j'avais mis 50 caractères mais que cela pouvait être personnalisé.

3) j'ai dis que la fonction mail pouvait être utilisée dans toutes les situations possibles et donc les 2 lignes servent pour d'autres situations, ce qui me parait intéressant au lieu de faire 50.000 fonctions pour chaque cas de figure !

4) pour la fonction filtre_stricte, elle porte le nom de stricte sous le commentaire : exemple

5) Ne pas filtrer un email de 1000 caractères et un pass de 1000 caractères ca ne va peut-être pas être très dangereux, mais au lieu de faire une requête pour rien qui sera refusée si la table est bien configurée
-> cela risque de pas mal gêner...

6) Puis pour ton histoire de password non sécurisé si pas d'utilisation de caractères spéciaux
-> faudrait revenir un peu dans la réalité car trouver 8 caractères contenant des minuscules, majuscules et chiffres
-> cela doit atteindre pas loin des 25 millions de possibilités
-> Donc même avec un programme -> bon courage
-> Puis la majorité des hacks qui sont répertoriés -> ce ne sont pas des passwords trouvés par miracle ou pas
( à cause d'un pauvre caractère spécial manquant).
-> Ca c'etait dans les années 70 quand tout le monde utilisaient des passwords du genre: 1234
-> Donc en imposant l'utilisation de majuscules, minuscules et chiffres -> c'est largement suffisant.
-> Et surtout cela sécurise le filtrage de données par la suite !

Si vraiment tu penses qu'avec un simple anti-slash tu vas empêcher toute injection SQL -> t'es vraiment loin de la réalité.
Par contre moi je conseil le filtrage de données d'une façon stricte -> et c'est la clef !

7) sujet clos pour ma part -> ++
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
AB
ViPHP | 5818 Messages

08 oct. 2009, 06:18

T'es drôle avec tes vérifications qui servent a rien :wink:
...
3) j'ai dis que la fonction mail pouvait être utilisée dans toutes les situations possibles et donc les 2 lignes servent pour d'autres situations, ce qui me parait intéressant au lieu de faire 50.000 fonctions pour chaque cas de figure !
Oui mais dans ce cas de figure une simple fonction native filter_var($email, FILTER_VALIDATE_EMAIL) suffirait pour savoir si l'utilisateur a rentré un mail erroné volontairement ou non.

...
5) Ne pas filtrer un email de 1000 caractères et un pass de 1000 caractères ca ne va peut-être pas être très dangereux, mais au lieu de faire une requête pour rien qui sera refusée si la table est bien configurée
-> cela risque de pas mal gêner...
Cela ne gênera pas plus qu'un mot de passe ou qu'un email erroné par erreur.
Mais bon, si tu veux faire un contrôle sur la longueur, utilises mb_strlen en spécifiant l'encodage si tu veux que ta fonction puisse travailler également efficacement en utf-8... puisque tu parlais de fonctions "utilisables dans toutes les situations" :wink:

...
6) Puis pour ton histoire de password non sécurisé si pas d'utilisation de caractères spéciaux
-> faudrait revenir un peu dans la réalité car trouver 8 caractères contenant des minuscules, majuscules et chiffres
-> cela doit atteindre pas loin des 25 millions de possibilités
-> Donc même avec un programme -> bon courage
-> Puis la majorité des hacks qui sont répertoriés -> ce ne sont pas des passwords trouvés par miracle ou pas
( à cause d'un pauvre caractère spécial manquant).
-> Ca c'etait dans les années 70 quand tout le monde utilisaient des passwords du genre: 1234
-> Donc en imposant l'utilisation de majuscules, minuscules et chiffres -> c'est largement suffisant.
-> Et surtout cela sécurise le filtrage de données par la suite !

Si vraiment tu penses qu'avec un simple anti-slash tu vas empêcher toute injection SQL -> t'es vraiment loin de la réalité.
Par contre moi je conseil le filtrage de données d'une façon stricte -> et c'est la clef !

7) sujet clos pour ma part -> ++
A moi de te dire que t'es trop drôle.

D'une part je ne t'ai pas dit qu'un mot de passe n'était pas sécurisé s'il ne contenait pas de caractères spéciaux, j'ai dit "qu'un mot de passe est d'autant plus sécurisé qu'il comporte des caractères spéciaux en plus de caractères alphanumériques".

Ton couplet sur les mots de passe ... aurait été largement mieux inspiré si tu t'étais documenté un minimum de chez minimum.

Je dis un minimum de chez minimum parce que quand je rentre "sécurité mot de passe" dans google, il me suffit de consulter par exemple les trois premiers résultats :

1/ Testeur de mots de passe qui est un lien microsoft.

A l'intérieur de cette page je clique sur le lien "lisez Mots de passe sûrs : création et utilisation" et je trouve :
De nombreux systèmes acceptent aussi l’utilisation de la barre d’espacement dans les mots de passe, vous pouvez donc créer une phrase de plusieurs mots (une phrase de passe). Une phrase de passe est souvent plus facile à retenir qu’un simple mot de passe, en plus d’être plus difficile à deviner pour autrui
Dans ce cas ta limitation de caractères serait incompatible...
...Combinez les lettres, les chiffres et les symboles...
Tiens donc...
Utilisez tout le clavier, pas seulement les caractères les plus communs. Les symboles produits en tapant un chiffre et en tenant la touche Maj enfoncée sont fréquemment utilisés. Votre mot de passe est beaucoup plus sûr si vous choisissez parmi tous les symboles qui se trouvent sur le clavier, y compris les signes de ponctuation qui ne sont pas sur la première rangée du clavier, ainsi que les symboles propres à votre langue
Ah bah ... ils sont lourds microsoft d'insister aussi lourdement.
Eh Dr@ke, tu devrais leur écrire pour leur enseigner les bonnes manières :mrgreen:


Bon passons à la deuxième ligne de résultats google

2/ La sécurité commence par de bons mots de passe et je lis :
Règle 2 :Votre mot de passe doit contenir un mélange de caractères alphanumériques et de caractères spéciaux (- + ! § %, ...)
Encore du courrier à faire... bon admettons ce lien n'est pas très récent.


3/ Mot de passe - Wikipédia
l'attaque par force brute : on se donne un espace de mots de passe à explorer en se fixant une longueur et un ensemble de caractères ; on énumère tous les mots de passe possibles de cet espace ; pour chacun de ces mots de passe on calcule l'empreinte par la fonction de hachage, et on compare cette empreinte avec celle que l'on a capturée. Pour empêcher ces attaques, l'utilisation d'un mot de passe long et complexe est recommandée. Par mot de passe complexe, on entend mot de passe comprenant différents types de caractères : des lettres minuscules et majuscules, des chiffres, et des caractères non alphanumériques (comme !:/#@ ...). La longueur du mot de passe assurera qu'il n'est pas énuméré lors d'une attaque par force brute : plus l'espace à énumérer est grand et plus l'attaque prend de temps. Voir le graphique ci-contre
Bon j'arrête là mes recherches, déjà ça te fait beaucoup de courrier à faire en tant que "spécialiste de la sécurité" pour dire à ces gens que ce sont des plaisantins et qu'ils ne savent pas de quoi ils parlent :mrgreen: :mrgreen: :mrgreen:

Mammouth du PHP | 985 Messages

08 oct. 2009, 06:44

Perso, j'avais juste répondu d'une façon détaillée a l'auteur du Post.
Une réponse qui me parait plutôt intéressante pour lui.
J'ai même fais un exemple de script.
Ensuite, pour le reste -> le plus simple c'est de me contacter directement par MP -> pour éviter ce genre d'incidents à l'avenir
-> Merci
Et en espérant que ma réponse ai pu aider l'auteur du Post. :wink:
Modifié en dernier par Dr@ke le 08 oct. 2009, 10:05, modifié 1 fois.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 4039 Messages

08 oct. 2009, 09:16

Bon, on arrête de nourrir dr@ke le troll, sami123 n'en a que faire de ce jeu de la plus grosse, et on retourne sur les injections.

J'ai un doute sur l'efficacité de mysql_real_escape_string().

D'ailleurs, ce lien montre bien des attaques pour y échapper.

Rien ne vaut les requêtes préparées ^-^
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Administrateur PHPfrance
Administrateur PHPfrance | 977 Messages

08 oct. 2009, 09:24

Modération :
Ce sujet dérive vers la polémique stérile ("troll").
Faute de revenir dans le sujet avec des interventions réellement constructives,
ce sujet pourra être verrouillé, voire supprimé, sans autre préavis.


Edit : s'il y a de nouvelle intervention de règlement de compte sur ce post, je le verrouillerai ! Merci de rester sur le sujet initial

ViPHP
AB
ViPHP | 5818 Messages

08 oct. 2009, 17:48

Bon, on arrête de nourrir dr@ke le troll, sami123 n'en a que faire de ce jeu de la plus grosse, et on retourne sur les injections.

J'ai un doute sur l'efficacité de mysql_real_escape_string().

D'ailleurs, ce lien montre bien des attaques pour y échapper.

Rien ne vaut les requêtes préparées ^-^
J'arrive pas à faire fonctionner ces attaques... Pourrais-tu me donner un exemple ?

Que dois-je mettre dans mes variables $email et $password ?

Code : Tout sélectionner

$email = '?'; $password = '?'; $sql = "SELECT COUNT(`email`) FROM membres WHERE email = '".mysql_real_escape_string($email)."' AND password = '".mysql_real_escape_string($password)."' LIMIT 1";