IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Sécurité d'une base de donnée


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut Sécurité d'une base de donnée
    Bonjour,

    j'aimerai vos avis, conseils sur la sécurité.

    J'aimerai l'améliorer dans mon code actuel.

    - j'ai déjà mis une "micro" protection (failleXSS) dans mon ajax avec
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    //on protège un peu l'url
        var yearURI = encodeURIComponent(annee);
        var monthURI = encodeURIComponent(mois);
        var acronymeURI = encodeURIComponent(acronyme);

    - je voudrais faire une protection contre les injections SQL
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    function sanitize_string($str) {
    	if (get_magic_quotes_gpc()) {
    		$sanitize = mysqli_real_escape_string(stripslashes($str));	 
    	} else {
    		$sanitize = mysqli_real_escape_string($str);	
    	} 
    	return $sanitize;
    }
    mais je ne sais pas trop où le mettre : controller ou model (je suis en MVC, mais les requêtes se font dans les classes modèles).

    -j'ai aussi ça ... mais on est d'accord que ça ne protège pas beaucoup non plus
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public function bindParam($param, $valeur){
            $type = "";
            if(is_int($valeur))
                $type = PDO::PARAM_INT;
            if(is_string($valeur))
                $type = PDO::PARAM_STR;
            if(is_null($valeur))
                $type = PDO::PARAM_NULL;
            if(is_bool($valeur))
                $type = PDO::PARAM_BOOL;
            $this->requete->bindValue($param, $valeur, $type);
        }


    - d'autre idée ?

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Passe à PDO, et utilise des requêtes préparées.

    Quant à ta fonction bindParam(), tu te trompes complètement.
    Ce n'est pas la valeur qui détermine le type, mais le type qui doit être imposé pour chaque donnée, pour correspondre au format de la colonne de la table SQL.

    N.B. get_magic_quotes_gpc() date de Mathusalem !

    Avertissement
    Cette fonction est OBSOLÈTE à partir de PHP 7.4.0. Dépendre de cette fonction est fortement déconseillé.
    Dernière modification par Invité ; 28/02/2020 à 14h56.

  3. #3
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    Bonjour,
    Passe à PDO, et utilise des requêtes préparées.
    Pas besoin de passer à PDO pour faire des requêtes préparées. Mysqli reste une option valable.

    Mais effectivement la bonne solution pour se prémunir des injections c'est les requêtes préparées , exemple en mysqli issue de la doc php :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
    $stmt->bind_param('sssd', $code, $language, $official, $percent); // sssd = 3 strings et un décimal
     
    $code = 'DEU';
    $language = 'Bavarian';
    $official = "F";
    $percent = 11.2;
     
    /* Exécution de la requête */
    $stmt->execute();
    Le principe là derrière étant que le server SQL "compile" dans un premier temps la requêtes et vient ensuite ajouter chaque paramètre à la requête. Les paramètres sont alors plus considéré comme de potentielle commande SQL mais comme de simple chaine de caractère.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par grunk Voir le message
    Mysqli reste une option valable.
    Tu parles, Charles...
    C'est une plaie en mysqli_.

    Va faire un $mysqli->bind_param() avec 30, 40, 50 données...
    Bonjour la galère (sans oublier le débogage et la maintenance !).

    D'autant que mysqli_ est à réserver à ceux qui veulent convertir un site existant * écrit en mysql_ sans se prendre trop la tête.

    * Je n'en ai converti qu'un seul en mysqli_ (à cause du changement de version PHP 5.6 -> 7.x sur le serveur).
    Tous mes autres sites sont en PDO.
    Dernière modification par Invité ; 28/02/2020 à 15h00.

  5. #5
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut précision
    Merci de votre intérêt.

    Alors précision qui a son importance, l'appli qui ne m'appartient pas (et que je n'ai pas droit d'essayer de l'upgrader, pas l'autorisation, pas le temps) est en PHP 5,6.

    J'essaie de faire au mieux avec ce que j'ai ...

    Et voilà un petit exemple de ce que j'ai dans mon Model :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public function getAllDataFromAuto($auto, $type, $de, $au){
            $this->bddData->query("SELECT * FROM " . $auto .
                " WHERE " . $type . " BETWEEN :de AND :au");
            $this->bddData->bindParam(':de', $de);
            $this->bddData->bindParam(':au', $au);
            return $this->bddData->fetchAll();
        }

    Je finis un stage, mais j'aimerai bien essayer de faire un truc un peu "propre".

  6. #6
    Invité
    Invité(e)
    Par défaut
    Déjà, remplace (partout) ->bddData par ->bdd.
    Ça t'économisera autant de fois 4 caractères...

    Et si tu veux faire "propre", débarrasse-toi des get_magic_quotes_gpc() !

    Quant à mysqli_real_escape_string(), tu peux/dois utiliser le style Orienté objet, comme tu le fais partout ailleurs.
    Dernière modification par Invité ; 28/02/2020 à 15h44.

  7. #7
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    Tu parles, Charles...
    C'est une plaie en mysqli_.

    Va faire un $mysqli->bind_param() avec 30, 40, 50 données...
    Bonjour la galère (sans oublier le débogage et la maintenance !).
    Je dis pas que c'est la meilleure option , je dis juste que c'est une option valable , au sens ou elle n'est pas dépréciée. La question porte sur comment sécuriser une requêtes faites actuellement en mysqli , pas est ce que c'est la meilleure solution.
    Entre nous si t'as 50 données à binder sur une requêtes le soucis il est pas dans le drivers SQL

    Et voilà un petit exemple de ce que j'ai dans mon Model :
    C'est quoi cet objet $this->bddData , un wrapper mysqli ? autre chose ?
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par grunk Voir le message
    C'est quoi cet objet $this->bddData , un wrapper mysqli ? autre chose ?
    Ca correspond à ça
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    /**
         * DataModel constructor.
         * @param $connexionData
         */
        public function __construct($connexionData){
            parent::__construct($connexionData);
            $this->bddData = new Database(
                $this->driver,
                $this->host,
                $this->database,
                $this->charset,
                $this->username,
                $this->password
            );
        }

    la classe DataModel.php
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    public function __construct($driver, $host, $database, $charset, $username, $password){
            $base = $driver . ':host='
                . $host . ';dbname='
                . $database. ';charset='
                . $charset;
            $options = array(
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
                PDO::ATTR_PERSISTENT    => false,
                PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
            );
            try{
                $this->bdd = new PDO($base, $username, $password, $options);
            }
            catch (PDOException $exception){
                $this->error = $exception->getMessage();
            }
        }


    Et si tu veux faire "propre", débarrasse-toi des get_magic_quotes_gpc() !

    Quant à mysqli_real_escape_string(), tu peux/dois utiliser le style Orienté objet, comme tu le fais partout ailleurs.
    Je ne l'ai pas utilisé, mais j'aimerai bien essayer de sécurité, pour éviter d'avoir trop de faille

  9. #9
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Ok , donc ta classe Database utilise déjà PDO. Et toi tu fais du mysqli.
    Il faut déjà que tu fasses la même chose partout et utiliser PDO partout et plus particulièrement ta classe Database.

    ET dans cette classe il ne faut plus faire de simple query mais des prepare/bind/execute qui te permettrons d'avoir des requêtes sécurisé. Et plus besoin des msqli_reals_escape ou magic_quote_gpc
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par grunk Voir le message
    Ok , donc ta classe Database utilise déjà PDO. Et toi tu fais du mysqli.

  11. #11
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut
    Citation Envoyé par grunk Voir le message
    Ok , donc ta classe Database utilise déjà PDO. Et toi tu fais du mysqli.
    Il faut déjà que tu fasses la même chose partout et utiliser PDO partout et plus particulièrement ta classe Database.

    ET dans cette classe il ne faut plus faire de simple query mais des prepare/bind/execute qui te permettrons d'avoir des requêtes sécurisé. Et plus besoin des msqli_reals_escape ou magic_quote_gpc
    Mais je les ai déjà dans Database.php.
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    /**
         * Prepare une requete
         * @param $requete
         */
        public function query($requete){
            ini_set('memory_limit', '1024M');
            if($this->bdd != null)
                $this->requete = $this->bdd->prepare($requete);
        }
     
     
        /**
         * Associe une valeur dans la requete
         * @param $valeur
         * @param $param
         */
        public function bindParam($param, $valeur){
            $type = "";
            if(is_int($valeur))
                $type = PDO::PARAM_INT;
            if(is_string($valeur))
                $type = PDO::PARAM_STR;
            if(is_null($valeur))
                $type = PDO::PARAM_NULL;
            if(is_bool($valeur))
                $type = PDO::PARAM_BOOL;
            $this->requete->bindValue($param, $valeur, $type);
        }
     
        /**
         *  Execute la requete
         */
        public function exec(){
            ini_set('memory_limit', '1024M');
            if($this->bdd != null)
                $this->requete->execute();
        }

    Mais je voudrais savoir s'il y a quelque chose à faire pour améliorer ... Sans avoir à tout refaire.

  12. #12
    Membre actif Avatar de Trehinos
    Homme Profil pro
    Analyste développeur PHP
    Inscrit en
    Novembre 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyste développeur PHP
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2012
    Messages : 99
    Points : 228
    Points
    228
    Par défaut
    Il n'y a rien à améliorer concernant l'insertion en BDD. Vous faites des requêtes préparées et ne créez pas de SQL à partir de chaînes PHP. A partir de là, vous rendez impossible toute injection SQL.

    Vous créez vos URI en échappant correctement vos variables... Là aussi, aucun risque de XSS dans une URL.

    Reste à faire des html_entities partout où vous imprimez (echo ou <?= ?>) une variable dans du HTML pour empêcher les XSS dans le HTML et vous êtes à un niveau normal de sécurité (normal = supérieur à la plupart des sites).

    Vous pouvez prendre le temps de lire cette partie de la documentation PHP pour des informations complémentaires : https://www.php.net/manual/fr/security.php

  13. #13
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut Remerciement
    Je te remercie pour ta réponse et pour le lien.

  14. #14
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut demande de précision
    Juste pour vérifier, mais grosso modo htmlentities se met sur toutes les variables qu'on récupère.

    Que ce soit dans un input, en post ... etc ...
    Les variables de SESSION aussi non ?
    Après tout elles peuvent être modifiées ...

  15. #15
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    htmlentities s'utilise sur toute variable à l'affichage.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  16. #16
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut framework
    Bonjour,

    Pour htmlentities : on m'a dit que les frameworks utilisant twig le gèrent de façon native.

    Le font-ils aussi pour les encodeURIComposent ?

Discussions similaires

  1. Sécurité d'une base de données
    Par salam2012 dans le forum Sécurité
    Réponses: 2
    Dernier message: 05/02/2013, 16h05
  2. Réponses: 14
    Dernier message: 01/08/2008, 11h45
  3. Réponses: 3
    Dernier message: 23/04/2007, 09h57
  4. Copie d'une base de données (Sécuritée)
    Par Mawashigeri dans le forum Outils
    Réponses: 3
    Dernier message: 27/02/2006, 20h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo