Table vidée de ma base de données mysql

Eléphant du PHP | 216 Messages

25 janv. 2015, 22:35

Bonjour à tous,

mon site internet à été hacké deux fois en quelques mois.
Plusieurs tables de ma base de données ont été vidée. Je pense qu'il s'agit d'injection mysql mais je n'en suis pas sûr.
Comment le savoir ?
Et comment y remédier ?
Voici par exemple mon code de connexion utilisateur présent sur toutes les pages :
if (isset($_POST['valide'])) // si clique sur le bouton ok
    {
    
        if(empty($_SESSION["mail"])) // si l'utilisateur n'est pas connecté
        {
            if(isset($_POST["mail"])) {$mail = $_POST['mail'];}	else { $mail = "";}
            if(isset($_POST["mdp"])) {$mdp = $_POST['mdp'];} else { $mdp = "";}
        }

        if(empty($erreur[0]))
        {
            include ('connect.php');
            /* on va d abord chercher si le client n'existe pas en effectuant un test sur la boîte mail */
            $sql = sprintf("select * from flatforswap_adherent where mail=%s and mdp=%s and valide !=%s", quote_smart($mail), quote_smart($mdp), quote_smart('0'));
            $req = mysql_query($sql) or die('Erreur SQL : <br />'.$sql);
              if (mysql_num_rows($req) == 1) 
              {
                 $data = mysql_fetch_assoc($req);
                 $valide = $data['valide'];
                 if ($valide == 2){
                 $verifexist = true;}
                 elseif($valide == 1){
                 $verifexist = false;
                 $erreurc[] = '<center><font color="#FF0000">'.$idem_txt0032.'</font></center>';}
              }
              else
              {
                $verifexist = false;
                $erreurc[] = '<center><font color="#FF0000">'.$idem_txt0033.'</font></center>';
              }
              mysql_close();
              if ($verifexist == 'true') 
              {
                $_SESSION['mail'] = $data['mail']; /* l'adhérent est maintenant connecté */
                
                include ('connect.php');
                // $sqld = sprintf("SELECT id_adh FROM flatforswap_adherent WHERE mail=%s", quote_smart($_SESSION["mail"]));
                // 20/04/2012 on rajoute la clause WHERE $valide = 2
                $sqld = sprintf("SELECT id_adh FROM flatforswap_adherent WHERE mail=%s and valide =%s", quote_smart($_SESSION["mail"]), quote_smart('2'));
                $reqd = mysql_query($sqld) or die('Erreur SQL : <br />'.$sqld);
                $datad = mysql_fetch_assoc($reqd);
                $id_adh = $datad['id_adh'];
                $_SESSION['id_adh'] = $id_adh; /* on met id_adh en session afin d'éviter des requête inutiles */
              }
        }
        
        // message d'erreur
        //if(isset($erreurc[0])) {for($i=0;$i<sizeof($erreurc);$i++) { echo $erreurc[$i];}} 
            
    }

Est-ce que cette requête a une faille ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

25 janv. 2015, 22:54

Une bonne pratique serait que tu utilises filter_var() pour filtrer toutes les variables dont tu ne maitrises pas l'origine, en gros tout ce qui passe par $_GET, _POST ou $_SESSION.

Pour éviter également les injections SQL, tu peux passer à PDO avec des requêtes SQL préparées.
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 216 Messages

25 janv. 2015, 22:58

Bonjour @rthur,

j'ai regardé le principe un peu le principe de PDO, mais je t'avoue que je n'ai pas tout compris.
Qu'est-ce donnerait mon exemple de requête de connexion en utilisant PDO s'il te plaît.
Ensuite, je m'appuierai sur cet exemple pour modifier la totalité de mes requêtes.

Merci d'avance pour ton aide.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

26 janv. 2015, 13:56

Utiliser PDO demande aussi de modifier la connexion à ta bdd, la modif est plus globale que juste changer ta requête.

Voici deux tuto assez bien fait sur PDO et les requêtes préparées :
http://www.experience-developpement.fr/ ... preparees/
http://studio.jacksay.com/tutoriaux/php ... l-avec-pdo
Quand tout le reste a échoué, lisez le mode d'emploi...

ynx
Mammouth du PHP | 586 Messages

26 janv. 2015, 17:22

Salut,

La méthode pour éviter les injections sql dépend de l'API utilisée (http://php.net/manual/fr/mysqlinfo.api.choosing.php) :
- avec l'API Mysql il faut utiliser la fonction mysql_real_escape_string() http://php.net/manual/fr/function.mysql ... string.php
- avec l'API Mysqli il faut utiliser la fonction mysqli_real_escape_string() http://php.net/manual/fr/mysqli.real-escape-string.php
- avec PDO il faut utiliser les requêtes préparées ou la méthode PDO::quote() http://php.net/manual/fr/pdo.quote.php

Puisque tu utilises actuellement l'api Mysql, il semble que tu puisses remplacer tes appels de quote_smart() par mysql_real_escape_string().

Bonne journée

Eléphant du PHP | 216 Messages

26 janv. 2015, 19:32

Bonjour ynx,

tu as raison, le plus simple pour moi serait d'utiliser :

mysql_real_escape_string

mais as-tu vu l'avertissement dans la doc ?

Avertissement

Cette extension est obsolète depuis PHP 5.5.0, et sera supprimée dans le futur. À la place, les extensions MySQLi ou PDO_MySQL doivent être utilisées. Voir aussi le guide MySQL : choix de l'API ainsi que la FAQ associée pour plus d'information. Voici les alternatives à cette fonction :

mysqli_real_escape_string()
PDO::quote()
Ils disent que cette fonction ne sera bientôt plus supportée.