Page 1 sur 2

sécurisé mon site

Posté : 24 oct. 2009, 13:21
par keviin1988
Salut,
cela fait un moment que je cherche à sécurisé mon site contre les injection sql et autre type d'attaque mais j'avance vraiment pas :( .Les tuto que je trouve sont contradictoire ...J'ai un accès à php.ini ,es que je doit mettre les magic quotes en OFF ?

Si j'écris se code pour une chaine de caractère comme paramètre
$ pseudo = mysql_real_escape_string ($ _GET [ 'pseudo']);
$ requete = mysql_query ( "SELECT age FROM membres WHERE pseudo = '$ pseudo'");

et se code pour un entier comme paramètre
$ id = intval ($ _POST [ 'id']);
$ requete = mysql_query ( "SELECT age FROM membres WHERE id = $ id");
es que mon site sera sure ?

je suis perdu , merci énormément d'avance

Re: sécurisé mon site

Posté : 24 oct. 2009, 14:15
par Dr@ke
J'ai un accès à php.ini ,es que je doit mettre les magic quotes en OFF ?
En théorie oui, d'autant plus qu'à partir de PHP 6, ils seront définitivement supprimés.
Donc oui, tu peux les mettre à OFF.
$ pseudo = mysql_real_escape_string ($ _GET [ 'pseudo']);
$ requete = mysql_query ( "SELECT age FROM membres WHERE pseudo = '$ pseudo'");
En théorie, c'est assez sécurisé si, et seulement si, tu utilises la fonction mysql_real_escape_string() et que tu entoures ta variable ensuite de simples guillemets.
Par contre, pour éviter les erreurs de Type Notice et certains bugs, il est préférable de toujours vérifier si la variable est définie avant...
Il est préférable aussi de prendre comme habitude aussi de toujours sortir les variables.
Donc:
$pseudo = (isset($_POST['pseudo'])) ? trim($_POST['pseudo']) : null;

if(!empty($pseudo)) {
$requete = mysql_query('SELECT age FROM `membres` WHERE pseudo = ' . "'" . mysql_real_escape_string($pseudo) . "'");
}
$ id = intval ($ _POST [ 'id']);
$ requete = mysql_query ( "SELECT age FROM membres WHERE id = $ id");
Avec une variable contenant un entier, effectivement aucun besoin d'utiliser mysql_real_escape_string() ou d'entourer la variable de simples guillemets si, et seulement si, on est certain que cette même variable contient bien un entier.
Donc en théorie, en utilisant la fonction intval(), oui cela est assez sécurisé.
Seul bémol: Vue que tu ne fais aucune autre vérification avant la fonction intval(), si l'utilisateur envoi un caractère particulier comme un @ -> cela risque de faire, je croie, planter le script.
Pour moi, l'utilisation de la fonction intval() dans ces circonstances est une erreur.
Donc je ferais personnellement, comme ceci:
$id = (isset($_POST['id'])) ? trim($_POST['id']) : null;

if(!empty($id) && ctype_digit($id)) {
$requete = mysql_query('SELECT age FROM `membres` WHERE id = ' . $id);
}
Ou si pour une raison particulière, tu as besoin de l'utilisation de la fonction intval() dans ce cas précis:
$id = (isset($_POST['id'])) ? trim($_POST['id']) : null;

if(!empty($id) && ctype_digit($id)) {
$requete = mysql_query('SELECT age FROM `membres` WHERE id = ' . intval($id));
}
Ou encore, si tu veux prendre en compte les lettres aussi:
$id = (isset($_POST['id'])) ? trim($_POST['id']) : null;

if(!empty($id) && ctype_alnum($id)) {
$requete = mysql_query('SELECT age FROM `membres` WHERE id = ' . intval($id));
}
Ou pour finir, si tu veux prendre en compte les "." aussi:
$id = (isset($_POST['id'])) ? trim($_POST['id']) : null;

if(!empty($id) && preg_match('#^[[:alnum:]\.]{1,}$#', $id)) {
$requete = mysql_query('SELECT age FROM `membres` WHERE id = ' . intval($id));
}
Il existe d'autres techniques et habitudes..., ici c'est juste un exemple :wink:

[EDIT]
Personnellement, j'ai toujours pris comme habitude en développement de toujours filtrer les données.
C'est à dire: vérifier les caractères des variables avec des c_type ou des preg_.
C'est une protection supplémentaire, parfois non indispensable mais souvent la seule solution véritablement fiable.
On est jamais à l'abri d'une erreur, d'un oubli ou d'un élément inconnu...

Sinon:
mysql_real_escape_string n'échappe ni % , ni _ . Ce sont des jokers en MySQL si combinés avec LIKE , GRANT , ou REVOKE .
Si magic_quotes_gpc est activée, appliquez d'abord la fonction stripslashes à vos données

Re: sécurisé mon site

Posté : 24 oct. 2009, 19:14
par Aureusms
Pour compléter, j'utilise, un peu dans l'optique des ctype les fonctions is_X comme is_string () is_numeric(), ...
Sinon comme dit dr@ke : faire toujours un isset() ou un empty() avant c'est mieux.
Comme ceci, si la variable reçu n'existe pas ou si elle n'est pas dans le bon format en plus de la protection slashes (tu as aussi la foncion php addslashes()) tu es à peu près bien sécurisé.

Un ch'tio conseil : créé toi une fonction cela reviendra à être plus rapide.

Re: sécurisé mon site

Posté : 25 oct. 2009, 03:54
par keviin1988
Merci énormément c'est très complet comme explication.Le problème c'est que je suis très débutant en php et pour terminer mon site sa ma pris un mois alors que l'un de vous le fera en moins d'une journée :(
voici un bout de mon code

Code : Tout sélectionner

<?php if( isset($_POST['email'])) { $email = (isset($_POST['email'])) ? trim($_POST['email']) : null; $email = (isset($_POST['pw'])) ? trim($_POST['pw']) : null; $_SESSION['email'] = $email ; $_SESSION['pw'] = $password; } else if (isset($_SESSION['email'])) { $email=$_SESSION['email']; $password=$_SESSION['pw']; } else { header('Location:index.php'); } //requête permettant de voir si l'utilisateur existe déja dans la base if(!empty($email)&&!empty($password)) { $sql = 'SELECT id_membres,statut FROM membres WHERE email = ' . "'" . mysql_real_escape_string($email) . "'" AND password = ' . "'" . mysql_real_escape_string($password) . "'" LIMIT 1'; } $query= mysql_query($sql); $result = mysql_fetch_array($query); $id=$result[0]; $_SESSION['id']=$id;
mais j'ai une erreur a cette ligne :(

Code : Tout sélectionner

$sql = 'SELECT id_membres,statut FROM membres WHERE email = ' . "'" . mysql_real_escape_string($email) . "'" AND password = ' . "'" . mysql_real_escape_string($password) . "'" LIMIT 1'; }
Pour ce qui es des fonction je sais pas trop comment les utilisés non plu :(
merci beaucoup de votre aide et d'avoir été là a chaque fois que j'ai u besoin d'aide :oops:

Re: sécurisé mon site

Posté : 25 oct. 2009, 15:02
par fab
Essaye plutôt :

$sql = 'SELECT id_membres,statut FROM membres WHERE email =  "'. mysql_real_escape_string($email) .'" AND password = "'.mysql_real_escape_string($password) .'" LIMIT 1'; 


Re: sécurisé mon site

Posté : 25 oct. 2009, 16:02
par Dr@ke
Je te conseil de télécharger et de regarder les script de zones membres sur cette page:
http://www.manuelphp.com/scripts/script ... re&idaff=2.

Utilise un des scripts et adapte le à ton propre site.
Ton script actuel présente plusieurs erreurs et incohérences.
Cela sera donc plus simple et plus sécurisé comme base de départ.
Si ensuite tu as besoin d'aide pour l'adapter ou le sécuriser, tu pourras re-poster un autre sujet...

Re: sécurisé mon site

Posté : 25 oct. 2009, 22:47
par keviin1988
Salut et merci pour t'as réponse,
non je tiens vraiment que le site soit entièrement mon œuvre, et pour les zones membres ça fonctionne très bien avec moi je ne vois pas où est le problème.
pour ma requête je crois que c'est bon :
$sql = 'SELECT id_membres,statut FROM membres WHERE email = "'. "'".mysql_real_escape_string($email). "'".'" AND password = "'."'" .mysql_real_escape_string($password)."'" .'" LIMIT 1'; 


es que mon bout de code est sure la ? j'ai entendu dire qu'il faut utilisé une fonction pour protégé les variable lors de l'affichage pour éviter les attaque "xss" si je m'en souviens bien.quelqu'un peut me donné une info sur ça ?
merci énormément pour tot

Re: sécurisé mon site

Posté : 25 oct. 2009, 23:21
par Dr@ke
Non ton code n'est pas sur car, comme je te l'ai dis, il comporte plusieurs erreurs et incohérences...

Sinon pour ta requête:
$sql = 'SELECT id_membres,statut FROM membres WHERE email = ' . "'" . mysql_real_escape_string($email) . "'" . ' AND password = '  . "'" . mysql_real_escape_string($password) . "'" . ' LIMIT 1';
Pour les failles Xss, il faut utiliser la fonction htmlspecialchars(), au moment de l'affichage des données, par exemple avec echo.

http://php.net/manual/fr/function.htmlspecialchars.php

Exemple:
// Au lieu de:
echo $email;
// faire:
echo htmlspecialchars($email);

Re: sécurisé mon site

Posté : 26 oct. 2009, 01:18
par keviin1988
Merci beaucoup,
es que tu peut me dire une erreur ou une incohérence ?
merci

Re: sécurisé mon site

Posté : 26 oct. 2009, 05:14
par fab
Par exemple après ton select tu vérifies pas si il existe bien des résultats! Tu encodes pas les caractères HTML, le password transit par l'utilisateur

Re: sécurisé mon site

Posté : 26 oct. 2009, 09:08
par Aureusms
J'ai pas lu les réponses en dessous mais tu écrases ta valeur récupérée en $_GET['email'] ?
if( isset($_POST['email']))
{
$email = (isset($_POST['email'])) ? trim($_POST['email']) : null;

$email = (isset($_POST['pw'])) ? trim($_POST['pw']) : null; // ICI
Edit : moi cela fait 4 ans que je bosses sur mon site. Dès que je pense avoir terminer : hop! nouveau script d'optimisation pour aller plus vite, plus sécurisé, plus... : tu n'en finira jamais selon moi. Surtout si tu suis l'informatique. C'est passionnant tu vas voir.

Re: sécurisé mon site

Posté : 26 oct. 2009, 13:14
par Ricou
Bonjour,
Je me permet de m'immiscer dans la conversation car c'est un sujet qui m'intéresse beaucoup.

J'aurais une petite question, quelle est la différence entre isnumeric et ctype_digit ? J'utilise seulement isnumeric sur mon site pour vérifier des enregistrements qui ne peuvent contenir que des nombres entiers, est-ce suffisant ou faut-il aussi utiliser des htmlspecialchars et des mysql_real_escape_string ?
J'ai essayé de mettre une arobase ou un pourcentage, et la vérification fonctionne bien sans planter.

Et fab, qu'appelles-tu : "le password transit par l'utilisateur" ?

Merci

Re: sécurisé mon site

Posté : 26 oct. 2009, 13:17
par fab
Tu stockes le password dans une variable de SESSION et c'est jamais très recommandé pour des questions de sécurité en cas de vol de cookie

Re: sécurisé mon site

Posté : 26 oct. 2009, 13:39
par Dr@ke
Bonjour,
J'aurais une petite question, quelle est la différence entre isnumeric et ctype_digit ? J'utilise seulement isnumeric sur mon site pour vérifier des enregistrements qui ne peuvent contenir que des nombres entiers, est-ce suffisant ou faut-il aussi utiliser des htmlspecialchars et des mysql_real_escape_string ?
Merci
is_numeric : http://php.net/manual/fr/function.is-numeric.php
ctype_digit: http://php.net/manual/fr/function.ctype-digit.php
$n = '1234.5';
$numeric_string = '42';
$integer        = 42;

var_dump(is_numeric($n));  // returns bool(true)
var_dump(ctype_digit($n)); // returns bool(false)

ctype_digit($numeric_string);  // true
is_numeric($numeric_string);   // true

ctype_digit($integer);         // false
is_numeric($integer);          // true

ctype_digit("-1")   //false
ctype_digit() n'accepte que des entiers (chiffres) positifs, cela dépend donc de ce que ta variable doit contenir...


mysql_real_escape_string : http://php.net/manual/fr/function.mysql ... string.php
mysql_real_escape_string() appelle la fonction mysql_escape_string() de la bibliothèque MySQL qui ajoute un slash aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.
Donc si ta variable contient un entier, inutile d'utiliser mysql_real_escape_string().

htmlspecialchars: http://php.net/manual/fr/function.htmlspecialchars.php
Les remplacements effectués sont :
* "&" (et commercial) devient "&amp ;"
* """ (guillemets doubles) devient "&quot ;" lorsque ENT_NOQUOTES n'est pas utilisée.
* "'" (guillemet simple) devient "& #039;" uniquement lorsque ENT_QUOTES est utilisée.
* "<" (inférieur à) devient "&lt ;"
* ">" (supérieur à) devient "&gt ;"
Donc même chose, si ta variable contient un entier -> inutile d'utiliser htmlspecialchars().

Re: sécurisé mon site

Posté : 26 oct. 2009, 15:21
par Ricou
Ouahhh, Drake, ça c'est de la réponse complète et argumenté et plus compréhensible que le manuel, merci.
Donc ne stockant que des entiers positif, ctype_digit serait plus approprié.
Il n'y a qu'un détail que je ne comprends pas bien, pourquoi ctype renvoi faux pour $integer = 42; ? Je croyais que les nombres n'avaient pas besoin d'être mis entre crochet pour être reconnu ? Et donc j'essaierai ce soir, mais que va renvoyer $integer = $_tableau['nombre']; ?

Tu stockes le password dans une variable de SESSION et c'est jamais très recommandé pour des questions de sécurité en cas de vol de cookie
Je croyais que les sessions étaient générées coté serveur et que au niveau client l'identification restait dans la ram. Enfin c'est pas grave, moi je ne le fais pas. :)


Et désolé de squatter ton topic kevin, j'espère au moins que ça va te servir.