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

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : injection sql: protection (changement de nom d'un precedent sujet)

par orgerix » 05 nov. 2007, 17:16

Par défaut, toutes les données envoyées par l'utilisateur doivent être protegé, en particulier les paramètres de connexion.

par choubix » 05 nov. 2007, 16:48

hello,

c'est interessant comme post!
dites moi: je m'apercois que vous ne securisez que l'email dans le formulaire.
il n'y a pas d'interet a securiser tous les champs? (dans mon cas: prenom, nom et email -ca va servir a un script de parrainage)

par orgerix » 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.

par Power Web » 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:

par Victor BRITO » 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:

par h0_noMan » 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.@-]

par Power Web » 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:

par Invité » 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 :)

par Berzemus » 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.

par Invité » 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?

par Berzemus » 05 nov. 2007, 11:03

Oublie la limitation par javascript, il suffit de le désactiver pour passer outre.

par choubix » 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?

par Power Web » 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 ;)

par choubix » 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. :)

par Power Web » 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 :)