injection sql: protection (changement de nom d'un precedent sujet)

Eléphant du PHP | 319 Messages

04 nov. 2007, 20:46

j'ai cru comprendre qu'un danger avec les formulaire est "l'injection sql"

a mon niveau de debutant, est-il possible de se proteger contre cela facilement?
(j'ai lu qq infos sur Google qui m'ont un peu degrossi sur ce que c'est mais pas trop sur comment eviter que les champs de formulaire ne soient detournes de leur vocation premiere)

merci!
Modifié en dernier par choubix le 05 nov. 2007, 04:50, modifié 1 fois.
niveau: pas terrible en php mais je me soigne...

Eléphant du PHP | 319 Messages

04 nov. 2007, 21:33

pour la securite des formulaires:

une petite recherche avec les BONS mots clefs m'a amene a trouver: mysql_real_escape_string()
a utiliser avec sprintf() afin d'eviter que les champs de formulaires soient proteges.

plus qu'a appliquer a tous les formulaires qui sont ouverts au public.
niveau: pas terrible en php mais je me soigne...

Eléphant du PHP | 61 Messages

05 nov. 2007, 02:33

Tu peux aussi utiliser htmlspecialchars() ou htmlentities() qui désactivé le HTML ainsi que addslashes() qui ajoutera des slash ;)

Choisis entre les différentes car de mettre tout c'est ridicule :wink:

Perso, j'utilise htmlentities() avec la constante ENT_QUOTES qui convertit les guillemets doubles et les guillemets simples :)
Modifié en dernier par Power Web le 05 nov. 2007, 16:31, modifié 1 fois.
Site sur THEOPERATION M.D. -> Nouvelle version (100%)
Ton code, tu indenteras; et le bohneur, tu feras.

Eléphant du PHP | 319 Messages

05 nov. 2007, 03:04

salut Power Web,

j'ai regarde la doc sur mysql_real_escape_string(). ca semble interessant.
j'ai utilise cette syntaxe:
$query = sprintf("SELECT email FROM clients WHERE email='$email'", 
			mysql_real_escape_string($email));
$result = mysql_query($query) or die ('Invalid query: ' . mysql_error());
j'utilise aussi sur d'autres requetes lors de l'enregistrement d'un nouvel utilisateur.
je ne trouve pas de difference avec et sans en l'occurence.

je fais des verifications lorsque le formulaire est rempli qui evitent d'avoir des soucis par la suite.

je vais regarder dans les fonctions que tu recommandes. :)
niveau: pas terrible en php mais je me soigne...

Eléphant du PHP | 61 Messages

05 nov. 2007, 03:25

Bonsoir, moi en fait j'utilise mysql_real_escape_string() pour sécurisé les variables ;)
Exemple:
if(isset($_POST['email']))
{
	$email = mysql_real_escape_string(htmlentities($_POST['email'], ENT_QUOTES));
     
	if(!empty($email))
	{
		$sql = mysql_query("INSERT INTO table VALUES($email)");
	}
  
	else
	{
		echo "Erreur : champs non remplis";
	}
}
Tu comprends maintenant ? En fait on sécurise la variable $email ^^ pour l'insérer par la suite dans la BDD ;)
Site sur THEOPERATION M.D. -> Nouvelle version (100%)
Ton code, tu indenteras; et le bohneur, tu feras.

Eléphant du PHP | 319 Messages

05 nov. 2007, 04:49

je comprends que tu prends le champs email, tu traduit le contenu en html puis tu verifies qu'il n'y ai pas d'injection sql avec mysql_real_escape_string()

je suis dans le vrai?

de mon cote j'ai utilise la syntaxe donnee dans le manuel pour mysql_real_escape_string()

ils mettent la verification au niveau de la commande sql seulement.

je me suis demande si ca avait du sens.

par contre je me suis aussi dit que pour se premunir contre les injection sql:
- limiter le nombre de carateres
- rejeter automatiquement certains caracteres (via javascript par exemple)
- verifier que la syntaxe de l'email est bonne

ca devait deja faire une bonne partie du boulot non?
niveau: pas terrible en php mais je me soigne...

ViPHP
ViPHP | 4039 Messages

05 nov. 2007, 11:03

Oublie la limitation par javascript, il suffit de le désactiver pour passer outre.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Invité
Invité n'ayant pas de compte PHPfrance

05 nov. 2007, 11:31

comment tu as ruine tous mes espoirs de ne pas avoir a trop toucher a mes scripts toi!! ;)

alros: est ce que ma syntaxe (qui est celle du manuel) suffit?
ou bien j'utilise cette de Power Web?

ViPHP
ViPHP | 4039 Messages

05 nov. 2007, 11:51

c'est dur la vie :cry:

Mais y'a plein de gens méchants, à l'affut de toute ouverture, et qui n'hésitent pas à te flinguer à la moindre occasion..

D'un manière générale, j'évite de faire des requêtes avec des données des utilisateurs, je les enregistre au préalable, je les compare, et j'effectue. Sauf bien sur quand je dois enregistrer des bazars dans une DB (avec, pour la sécurité, un utilisateur pour consulter et un autre pour enregistrer, si possible), ou envoyer un mail.. et un formulaire d'envoi de mail, c'est hyper-recherché, vu que c'est facilement exploitable.. un captcha me semble nécessaire, rien que pour empêcher l'envoi massif de mails.
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Invité
Invité n'ayant pas de compte PHPfrance

05 nov. 2007, 12:49

hum: j'ai trouve pas mal de tutoriaux pour les captchas. reste a savoir ce que je fais...

ou alors je peux valdier a mano les emails a envoyer. mais bon: ca tue le charme du php qui me permet d'automatiser un maximum :)

Eléphant du PHP | 61 Messages

05 nov. 2007, 15:04

par contre je me suis aussi dit que pour se premunir contre les injection sql:
- limiter le nombre de carateres
- rejeter automatiquement certains caracteres (via javascript par exemple)
- verifier que la syntaxe de l'email est bonne
Salut,

Pour la limite tu peux faire ça via HTML

Code : Tout sélectionner

<input type="text" name="email" maxlenght="30" />
En changeant 30 par le nombre de caractères que tu veux ;)

Ou PHP avec la fonction substr()
$email = substr($_POST['email'], 0, 30); // Pareil tu changes 30 par le nombre que tu veux
Pour la syntaxe de l'email tu peux utiliser une regex avec preg_match() :wink:
if(preg_match("#^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$#", $_POST['email']))
{ 
     // Bon email 
}
else { 
     // Mauvais email 
}
Et pour interdire les caractères je sais pas ... Mis à part les regex peut-être :-k

Comme ça :
if(preg_match("#[ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\!\?\:\.]#i", $_POST['email']))
{
     echo "Votre email ne doit pas contenir de caractères spéciaux";
}
Ou tu remplaces tout simplement les caractères spéciaux avec la fonction strtr()

Bon courage :wink:
Site sur THEOPERATION M.D. -> Nouvelle version (100%)
Ton code, tu indenteras; et le bohneur, tu feras.

Eléphant du PHP | 445 Messages

05 nov. 2007, 15:32

Pour l'email il serait plus simple de vérifier les caractères autorisés que ceux interdit.

[A-Za-z0-9.@-]

Mammouth du PHP | 2937 Messages

05 nov. 2007, 16:13

Une autre solution, lorsqu'on est en PHP 5 et qu'on est susceptible de passer d'un SGBD à un autre, consiste à utiliser les requêtes préparées de PDO, qui échappent automatiquement les caractères spéciaux.
<?php 
// Tentative d'injection SQL
$identifiant = "Pierre' -- ";
$mdp = '';
$pdo = new PDO ('mysql:host=localhost;dbname=ma_base', 'root', 'mdp');
$requete_preparee = "SELECT identifiant FROM table WHERE identifiant=:identifiant AND mdp=:mdp";
$requete = $pdo -> prepare ($requete_preparee);
$requete -> execute (array (
  ':identifiant' => $identifiant,
  ':mdp' => md5 ($mdp);
));
$resultat = $requete -> fetch ();
// La dernière ligne aura de fortes chances de retourner un tableau vide (aucun résultat trouvé)
// L'injection SQL est donc voué à  l'échec
?>
Cet exemple montre bien que, sans préparation de requête ou d'échappement de chaînes, j'enverrais la requête suivante :

Code : Tout sélectionner

SELECT identifiant FROM table WHERE identifiant='Pierre' -- AND mdp=''
qui ne serait pas la requête attendue (puisque la fin a été mise en commentaire) et me permettrait d'accéder à la partie membres sans nécessiter de mot de passe. :twisted:

Eléphant du PHP | 61 Messages

05 nov. 2007, 16:25

Pour l'email il serait plus simple de vérifier les caractères autorisés que ceux interdit.

[A-Za-z0-9.@-]
Ouai en effet suis-je bête! Sinon on devrait écrire tout les caractères spéciaux que l'on ne veut pas... Juste un peu long :lol:
Site sur THEOPERATION M.D. -> Nouvelle version (100%)
Ton code, tu indenteras; et le bohneur, tu feras.

Mammouth du PHP | 693 Messages

05 nov. 2007, 16:29

Pour les données numériques, il faut verifier si ce sont des nombre avec la fonction is_numeric() car avec celles ci, les injections se font sans caractères spéciaux.