Annonce ToutSurTout

Bienvenue sur toutsurtout.biz

Déjà 15 ans !

Radio TST

Si vous souhaitez participer vous aussi aux discussions sur le forum, il faut vous inscrire ou vous identifier.

Le Thème TST Automne est maintenant en place.

Les inscriptions sont actuellement OUVERTES.

Message 1 Discussion postée le 17-06-2012 à 14:20:27

Loic
Avatar de Loic


Titre: Administrateur d'élite
Avancement: Niveau 5
Lieu: Avec Solenne
Date d'inscription: 26-09-2009
Messages: 107 780
Site web

Failles Web, s'en protéger

Les Injections SQL :

Qu'est-ce que c'est ?
Les Injections SQL, ont pour but comme son nom l'indique, d'injecter des requêtes SQL dans la BDD.
Vous allez me dire, rien d'inhabituel, après tout, c'est ce qu'on fait en php. Sauf que là, c'est le client qui a la possibilité d'en faire.

Dans quel but ?
Tout simplement pour récupérer des infos perso collectées dans la BDD, comme par exemple le mot de passe de l'admin, et dans le pire des cas, les infos bancaires des membres.

Comment ?
On peut injecter du code SQL via les formulaires, ou via l'url.

Voici un formulaire de connexion simple coté html :

<form action="script.php" method="post">
    <input type="text" name="pseudo" />
    <input type="password" name="pass" />
    <input type ="submit" value="Se Loguer" />
</form>

Et voici le coté php non protégé :

if(isset($_POST) && !empty($_POST['pseudo'])) && !empty($_POST['pass'])){
     extract($_POST);
     $sql = "SELECT * FROM membres WHERE pseudo='$pseudo' && pass='$pass'";
     $req = mysql_query($sql);

     if(mysql_num_rows($req) !=0){
         // Création des sessions etc....
         echo "Le membre $pseudo est connecté";         
    }else
         echo "Mauvais identifiants";
}

Vous vous demandez : "mais où se situe le problème ?"
Et la réponse se joue dans la requête.

Si dans pseudo j'entre ceci : "admin" (pseudo du compte admin)
et dans pass j'entre ceci : " ' OR 1=1 "(propriété toujours vérifié)

Alors la requête deviendrait ceci :

SELECT * FROM membres WHERE pseudo='admin' && pass='' OR 1=1"

En gros, le gars vient de se connecter avec le compte admin sans avoir son pass.

L'autre méthode pour les failles de type injection SQL est via les url (GET donc).
Regardez ce code :

if(isset($_GET['id']){
   $req = "SELECT * FROM topic WHERE id = ".$_GET['id'];
}

Ce code sélectionnera le topic en fonction de l'id tapé dans l'url.
Là aussi rien d'anormal, sauf que si !

Si le membre s'amuse à taper une requête c'est foutu.

SELECT * FROM topic WHERE id = '' UNION SELECT * FROM membre WHERE id = 1

Et voilà un simple requête permettant de tout obtenir de l'admin (pseudo, pass, mail , ip) ...

Comment se protéger ?

La fonction intval() : Elle permet de prendre la valeur entière d'un nombre (1.3 deviendra 1)
La fonction htmlspecialchars() : Permet de se protéger des failles XSS
La fonction mysql_real_escape_string() : Permet de contrer les différentes failles d'injection SQL en ajoutant des antislash devant les guillemets ou apostrophe. En les échappant. Ainsi ils n'auront plus aucune utilité.

Pourquoi ne pas utiliser addslashes() ?
Tout simplement car cette fonction n'échappe pas tous les type de caractères.

Et concrètement au niveau du code ça donne quoi ?

Pour le formulaire de contact :

if(isset($_POST) && !empty($_POST['pseudo'])) && !empty($_POST['pass'])){
     extract($_POST);

     $pseudo = htmlspecialchars($pseudo);
     $pass = htmlspecialchars($pass);
     $sql = "SELECT * FROM membres WHERE pseudo='".mysql_real_escape_string($pseudo)."'
&& pass='".mysql_real_escape_string($pass)."'";
     $req = mysql_query($sql);

     if(mysql_num_rows($req) !=0){
         // Création des sessions, etc....
         echo "Le membre $pseudo est connecté";
    }else
         echo "Mauvais identifiants";
}

Pour l'affichage des topics :

if(isset($_GET['id']){
   $id = intval($id);
   $req = "SELECT * FROM topic WHERE id = "$id;
}

C'est simple non ? Alors pensez y !

La faille Include :

Deuxième faille à étudier, la célèbre faille include.
La faille include se résume en une simple phrase :
Elle permet d'insérer une page web distante dans un site.

Concrètement il suffirait de taper ceci : http://www.nom_du_site_faillible.com/index.php?p=http://www.google.fr
Et ça inclurait le site de google.

Comment ?
C'est simple, regardez ce code :

include($_GET['p']);

Il inclura toutes les adresses entrées dans l'url (sauf si le serveur est bien configuré)

Est-ce réellement grave ?
Sans trop vous vouloir vous alarmer, oui !!! Très GRAVE !!!
Il existe des scripts permettant de récupérer la totalité du serveur (ftp et mysql), ainsi que le pass des admin via bruteforce. Bref une horreur !

Comment se protéger ?
Tout simplement en filtrant les pages.
C'est votre serveur ? Donc vous savez quelles sont les pages dessus.

Admettons qu'il y ai 3 page (index, contact et galerie) :
Il faudrait faire ceci :

if(isset($_GET) && $_GET['p'] == "galerie"){
    include('gallerie.php');
}elseif(isset($_GET) && $_GET['p'] == "index"){
    include('index.php');
}elseif(isset($_GET) && $_GET['p'] == "contact"){
    include('contact.php');
}

Ainsi, le hackeur ne pourra plus rien faire.

Conseil général :

Les failles WEB existent uniquement car vous (en tant que codeur) laissez la possibilité aux hackeurs de s'en servir.
N'oubliez jamais de filtrer absolument toutes les variables d'entrées et de sorties.
Enfin, toutes les failles ne sont pas forcément aussi complexe que l'on pourrait le penser. Un simple oubli de vérification dans le code peu devenir une faille.
Pensez à tester vos codes et à les faire tester avant de mettre en ligne vos projet.


http://www.toutsurtout.biz/img/UserBarTST.gif
http://www.toutsurtout.biz/img/Sign-Loic.gif
Loic DL un jour, Loic DL toujours ...