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é PHP / Mysql - Injections SQL


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Par défaut Sécurité PHP / Mysql - Injections SQL
    Bonjour,

    Avant tout veuillez m'excuser si ce sujet a déjà été abordé dans le forum : après une recherche je n'ai trouvé que la référence d'un livre (Sécurité PHP 5 et MYSQL). J'ai malheureursement peu de temps à disposition pour m'intéresser à ces 300 pages (mais je le ferai cerrtianement par la suite).

    Je ne suis pas développeur mais chef de projet, j'ai donc une vision globale des rapports infra/système & réseau/couche applicative.

    Je me suis lancé un challenge personnel, à savoir développer un site ecommerce avec mes connaissances basées sur des années d'expérience en entreprise (+ des connaissances personnelles en scripting ou programmation (niveau neuneu)).

    Mon propos est ici de me placer au niveau du code, et de la sécurité des appels de base mysql dans un environnement WAMP (ou Xamp sur Linux).

    J'ai en effet (à ma grande surprise) réussi à développer une bonne partie du site après avoir consulté de nombreux tutos et de nombreux sites d'entraide (en me contentant des réponses apportées), mais au final, m'étant renseigné sur le risque d'injection SQL, je me vois contraint de revoir tout le code afin de le sécuriser.

    Ma question est donc la suivante : Y a-t-il un moyen sûr ou une méthode sure de coder en structurant son code dans différents fichiers, par exemple script principal, appelant un script où sont définies les variables, un autre les fonctions (javascirpt par ex) et un autre les instructions SQL ? ou cela n'a-t-il aucune incidence ?

    Deuxième question qui vient compléter la première : Afin d'éviter des intrusions, qu'est-ce qui ne doit pas circuler exactement entre un client et un serveur ? (plutôt que de décrire uniquement comment protéger l'accès aux valeurs des variables).

    Je ne vais pas m'aventurer à mettre un bout de code ici car il s'agit de décrire une méthode globale.

    J'ai pour ma part effectué des appels de bases classiques avec les instructions INSERT et SELECt essentiellement.

    Je suis au courant pour les escapestring concernant l'appel des valeurs de la base avec $_post ou $_get, afin de protéger l'accès aux valeurs de la base, ainsi que des méthodes préparées.

    Est-ce cependant suffisant ? Le risque d'injection ne vient-il pas plutôt (ou également) de la manière de coder son PHP ?

    Si j'ai bien compris un hacker ne s'attaque pas au php (côté serveur -à moins d'une superfaille au niveau authentification), mais profite de la relation client/serveur pour introduire des données qui peuvent corrompre la base ou lancer des instructions sur la base pour accéder à ses valeurs.

    Ce sont ces points que j'aimerais éclaircir.

    Merci pour qui m'aura compris, qui aura le courage de faire un mini-tuto sur ces demandes de manière "fonctionnelle" et globale (sans rentrer dans des détails de code si possible) et désolé de la longueur du POST.

  2. #2
    Membre chevronné Avatar de Inazo
    Profil pro
    Gérant - société de développement web
    Inscrit en
    Avril 2007
    Messages
    417
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Gérant - société de développement web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 417
    Par défaut
    Bonjour,

    Alors ce n'est pas grave si le sujet à déjà été abordé cela fera une bonne piqure de rappel pour certain

    Pour répondre à ta question d'une manière générale OUI mysql_real_escape_string te protègera des SQLi (Injection SQL) par contre sur le tutoriel que tu donne en exemple il y a une absurdité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $requete = mysql_query("SELECT age FROM membres WHERE pseudo='$pseudo'");
    L'utilisation de guillemet pour inclure la variable pseudo peut faire courrir un risque à l'application car PHP va interpréter le code $pseudo pour le jouer dans le code et cela peut être très dangereux. De plus l'utilisation de guillemet et fortement consommatrice de ressource car justement PHP recherche entre guillemet des éléments à exécuter en tant que code PHP...

    Exemple ou mysql_real_escape_string est inefficace :

    Si ma requete est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $IsDo = mysql_query('SELECT * FROM toto WHERE id='.mysql_real_escape_string($_GET['donnelabmda']));
    Si je met dans $_GET['donnelabmda'] ceci : "1 OR 2<>3" mysql_real_escape_string n’échappera aucun caractères et l'injection marchera sans soucis. Et je pourrais réaliser des requêtes voir sous requêtes complexe.

    Donc toujours écrire comme ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $IsDo = mysql_query('SELECT * FROM toto WHERE id="'.mysql_real_escape_string($_GET['donnelabmda']).'"');
    Le but étant d'avoir toujours des guillemets qui entoure les valeurs donné à MySQL provenant de variable non sur (variable saisie par l’utilisateur ou pouvant être altéré tel que USER_AGENT)

    Il vous est aussi possible d'utiliser la librairie PDO pour sécuriser vos requêtes SQL par contre attention une fois encore tout comme pour mysql_real_escape_string il faut l'utiliser de manière correct.

    Si j'ai été trop vague ou que vous avez d'autres question n'hésitez surtout pas

    Cordialement,

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Par défaut
    Je suis pas sûr de bien comprendre, JC.

    Que fais-tu de ça ?

    Citation Envoyé par Inazo Voir le message
    Exemple ou mysql_real_escape_string est inefficace :

    Si ma requete est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $IsDo = mysql_query('SELECT * FROM toto WHERE id='.mysql_real_escape_string($_GET['donnelabmda']));
    Si je met dans $_GET['donnelabmda'] ceci : "1 OR 2<>3" mysql_real_escape_string n’échappera aucun caractères et l'injection marchera sans soucis. Et je pourrais réaliser des requêtes voir sous requêtes complexe.

    Donc toujours écrire comme ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $IsDo = mysql_query('SELECT * FROM toto WHERE id="'.mysql_real_escape_string($_GET['donnelabmda']).'"');
    Le but étant d'avoir toujours des guillemets qui entoure les valeurs donné à MySQL provenant de variable non sur (variable saisie par l’utilisateur ou pouvant être altéré tel que USER_AGENT)
    Autrement dit, je pense qu'il serait bon de récapituler en classifiant les injections possibles de hackers en fonction de leur type (sans les écrire, pour ne pas donner de mauvaise idées). Exemples :

    - Récupération de valeurs
    - Introduction de valeurs
    - Modification de requêtes
    - ...

    Avec un exemple de code montrant la protection à apporter à chacun d'entre eux.

    J'ai cru comprendre qu'il faut avant tout séparer les variables users récupérant des valeurs de la table lors de requêtes (ou en introduisant), par des variables intermédiaires (puisque la valeur d'une variable est stockée en mémoire sur le serveur qui exécute le script - et donc inaccessible (à part localement par un admin voyou)).

    D'où :

    Citation Envoyé par tse_jc Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $id=intval($_GET['id']);
    $requête=mysql_query("SELECT age FROM membres WHERE id=$id");
    Maintenant, faire la part des choses sur l'utilisation des guillemets entre la syntaxe du code d'un côté et la sécurité au niveau injection de l'autre ne m'apparaît pas si évident que cela.

    En effet, tes différents exemples ne mettent pas en évidence le rapport PHP/Mysql qui nous intéresse ici.

    Merci de bien vouloir (à qui voudra bien) faire un récap structuré avec des étapes claires en fonction du type de risque. On pourrait d'ailleurs mettre à chaque étape "A faire", et "A ne pas faire". Une petite explication serait la bienvenue à chaque étape, pour bien identifier où se situe le risque.

    C'est le but originel du POST et ça servira à d'autres.

    Merci à vous tous.

  4. #4
    Membre éprouvé Avatar de redoran
    Homme Profil pro
    Développeur-Amateur
    Inscrit en
    Juin 2010
    Messages
    1 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur-Amateur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 346
    Par défaut
    En effet, tes différents exemples ne mettent pas en évidence le rapport PHP/Mysql qui nous intéresse ici.
    367 affichages avec 24 post , vue l'importance du sujet chaque élément est important afin d'adopter une réaction de fond , et l'exemple sur utilisation des des guillemets toutes équivalentes se n'est que pour mettre en évidence leurs action ensuite sa reste a voir leurs effets sur les requêtes.
    je crois que le problème de sécurité dépasse de loin les guillemets.

  5. #5
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Je dois bien avouer que je suis très surpris de vos réactions, car il me semble humblement qu'il s'agit de choses fondamentales que le considère peut être à tort de problème de débutant. Enfin je me pose maintenant la question.

    Peut être que le problème de la confusion viens en fait de l'utilisation de fonctions génériques dont finalement on ne prends pas trop la peine de savoir ce qu'elles font exactement (peut être le café aussi?^^) et on se fie aveuglément à ce qui est dit ou recommandé sans se soucier réellement des véritables enjeux et contraintes de nos développements.

    Je vous fais un copier coller d'une recommendation que j'avais faite dans un autre forum pour comprendre de façon générale comment doit être construit un code:

    Citation Envoyé par jc
    Quand vous développez une fonction pour accomplir une tache A à partir d'un paramètre p (ou plusieurs)
    1) La fonction ne sait pas ce qu'est p si ce n'est un paramètre : Assurez vous de la bonne valeur du paramètre p avant de le valider et retourner un message d'erreur ou un Numéro d'erreur pour chaque mauvaise valeur de p qui est tentée d'être passée à la fonction.
    2) Une fois qu'on est sur de la valeur de p ainsi que de son format, sa nature, etc... traiter l'information donnée par le paramètre avec une gestion d'erreur associée à tous les stades du processus.
    3) retourner la valeur de resultat de la fonction d'une manière standard (date, etc...), et réserver un rendu particulier de valeur qu'au moment de l'affichage.
    Dit différemment il ne faut jamais faire confiance aux paramètres reçus du côté PHP (et idéalement côté SGBDR aussi mais il s'agit d'un autre débat).

    Je vais essayer donc de donner une méthodologie dans le contexte donné ici qui est le rapport PHP/MySQL.

    Il faut prendre conscience avant tout que le contexte PHP/MySQL ne crée pas de contexte spécifique particulier à partir du moment où l'on code comme l'on doit coder c'est à dire en s'assurant à tous les stades du programme de la qualité de l'information traitée.

    Une injection SQL c'est quoi de façon générique?
    C'est le passage d'un paramètre à une requête SQL dont le contenu, la valeur n'est pas celui/celle qui est censé(e) être reçu(e) par cette requête.

    Donc une mauvaise valeur de paramètre peut être
    1) Sans incidence pour la sécurité de l'application
    2) Peut provoquer des dommages considérables (accès non autorisé, etc...) : c'est de ce cas dont il s'agit quand on parle communément d'injection SQL.

    La méthode à appliquer pour éviter des injections devrait être maintenant claire pour tout le monde. Mais détaillons tout de même.

    Que sont d'abord les variables $_GET, $_POST, $_REQUEST, etc.. ou encore les paramètres d'une fonction php? (ex: function myfn($p,$q){ } )

    Ce sont des paramètres publics pour votre application et donc des paramètres dont vous ne pouvez pas connaître leur contenu dans l'absolu. Pensez le contraire, et tôt ou tard votre application connaîtra des problèmes de sécurité voire d'injection.

    Première règle "anti-injection"
    Ne jamais passer ces paramètres directement en validation de traitement (cf quotes du post précédént).

    Voyons les autres "règles" par l'exemple.
    1) cas d'un entier (valeur censée être récupérée) passée en $_GET (méthode à adapter et à appliquer pour toute variable publique).
    Pour éviter de générer aussi des erreurs on va regarder ce qu'elle contient.
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if (isset($_GET['id'])){$id=intval($_GET['id']);}else{$id=0;} // on s'assure ici que la variable existe, auquel cas on la re-type comme entier et quelque soit le contenu de $_GET['id'] on aura bien un entier dans $id, sinon on initialise notre variable locale $id (qui est une recommendation aussi et évite bien des heures de débogage inutilement)
    // on peut maintenant passer notre variable locale $id dans notre requête car on est certain de son contenu
    $sql="SELECT id, colonneA, colonneB FROM MYTABLE WHERE id=$id";

    2) Pour les chaînes de caractères
    Le cas est un peu plus complexe car retyper une chaîne de caractères ne permets pas de s'assurer de sa bonne valeur. Il faut donc étendre notre traitement. Celle que je préfère, et déjà évoquée précedemment, est d'utiliser une expression régulière car elle est suffisante et à l'avantage dans un contexte de base de données, de contrôler la qualité de l'insertion ou la mise à jour dans la base: on s'assure en plus du contenu que le format d'écriture de la donnée est conforme à notre standard d'écriture choisi dans la base. Donc elle a bien un double avantage non négligeable.

    Que faire lorsque aucun pattern de contenu n'est applicable? c'est à dire quand il ne s'agit pas d'un numéro de téléphone, de pays, bref de donnée déjà définie par un standard quelconque ou un standard propre à votre application?
    Il suffit tout simplement de convenir au niveau applicatif, en prévenant l'utilisateur, des caractères qui ne sont pas acceptées à la saisie. Vous pourrez ainsi vérifier leur présence via une expression régulière et ainsi une valeur de type "1 OR 2<>3" n'a plus de raison d'être présente.
    On aurait donc
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (isset($_GET['chaine'])){$mychaine=$_GET['chaine'];}else{$mychaine="";}
    if (!preg_match($pattern,$mychaine)){throw exception('erreur dans paramètre $chaine');}
    // arrivé ici on est certain que le contenu de $mychaine est conforme à nos attentes et par conséquent est SAFE pour l'application.
    // cependant si les guillemets ou les apostrophes sont acceptés dans le pattern, il faudra les echapper pour eviter une erreur SQL à l'insertion ou à la mise à jour
    $mychaine=addslashes($mychaine); // si la chaîne peut contenir des apostrophes ou des guillemets. (peut être remplacé par QUOTE() dans la requête).
    $mychaine=utf8_encode($mychaine); // si necessaire.
    $sql="SELECT id, colonneA, colonneB FROM MYTABLE WHERE colonneA='$mychaine' ";
    Vous l'aurez compris donc pour la question des guillemets posée initialement il s'agit tout simplement d'un problème de syntaxe d'écriture de PHP qui n'a rien à voir avec l'injection de près ou de loin.

    J'espère n'avoir rien oublié et que maintenant tout est clair pour ceux que cela interesse^^.

  6. #6
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Un petit complément d'information qui n'est qu'un simple avis personnel si vous me le permettez concernant le lien fourni (je ne sais plus par qui) mais qui est celui-ci :
    http://stackoverflow.com/questions/6...ection-in-php/

    Faire des requêtes préparées en ayant pour seul objectif d'éviter les injections SQL n'est pas une bonne pratique en soi. Ceux qui la prônent c'est encore et une fois de plus les partisans du moindre effort. C'est ceux qui pensent que tout ce que l'on viens de dire = OSEF je fais nimp et comme je veux et à la fin, hop, une petite requête préparée et le tour est joué plus d'injection SQL.

    Une requête préparée en SQL, sans rentrer dans les subtiles différences, c'est un peu comme lorsque l'on fait du currying en javascript (sur l'ensemble ou partie des paramètres en SQL et sur partie uniquement des paramètres en Js). L'intérêt primaire d'une requête préparée est de pouvoir rejouer la requête et donc le même plan de requête successivement avec des paramètres différents, beaucoup plus performant qu'un

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for($a=0;$a<1000;$a++){mysql_query("INSERT INTO MYATABLE (colonneA) VALUES ($a)");}

    même en proc stock.

    Déjà qu'en proc stock on est obligé de passer par une requête préparée pour toute requête statique générée dynamiquement (sauf à utiliser les user variables), et pour toutes les requêtes dynamiques. C'est largement suffisant.

    ++




    En effet si on veut être certain du comportement d'une application et que l'on a besoin de garantir cela à un client, il faut le vérifier soi même.

  7. #7
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    salut,

    vaste sujet...

    y a pas de réponse simple, car rien n'est jamais vraiment sécurisé vu les différents angles d'attaque que tu peux avoir...
    regarde les pauvres types de chez yahoo et leurs 450000 comptes piratés grâce à une faille sur un sous domaine...

    tu ne peux qu'essayer de maximiser les bonnes pratiques mais par principe rien ne garantira jamais que suite à la mise à jour de telle ou telle couche logicielle, un jour une faille n'apparaitra pas (exemple ssl avec une des récente mise à jour java)... ça c'est la première faiblesse de toute technologie elle même dépendante d'autres comme sous-couches...

    le 2ème point faible le plus commun, l'hébergement des services (mysql, apache, etc...) et la configuration (que celui qui possède l'hébergement) peut plus ou moins changer... exemples:
    • un grand classique c'est l'injection de valeurs dans des variables php selon les réglages de php.ini
    • le fait de mettre le chmod dans un répertoire à 777 pour de la manipulation de fichier sur LAMP... du coup une fois le fichier en place, il est exécutable


    je te ferais même pas la liste des protocoles réseaux qui sont en soit une faille car conçus, originellement comme croyant celui qui répond et jamais modifier car trop de chose marche grâce à eux au niveau matériel... allé un petit exemple pour voir à quel point tu peux être attaqué sur des niveaux insoupçonnés...

    enfin le grand classique selon le niveau des hacker, le sniffing permettant l'analyse des paquets échangés pour du reverse engineering et l'extraction de données, identifiant, mot de passe...

    les attaques brutes de force, l'utilisation de rainbow table pour collisionner (casser) un mot de passe...

    après, questions bonnes pratiques php(ou autres)/mysql(ou autres) sont simples en général:
    • séparer le traitement sql du code php (comme on sépare le html du style)tant que faire ce peut:
      • utiliser un user ayant qu'un "grant execute" et des procédures stockées pour masquer ce qu'il y a dans la bd
      • ne JAMAIS utiliser de mot de passe et d'identifiant sql avec des droits sensibles dans le code, s'il y a la moindre chance qu'il soit récupéré ou lu par un hacker (surtout dans les applications de jeu ou avec des données sensible en java, c#, etc...) si la connexion est pensée comme devant se faire coté client(navigateur)... c'est d'ailleurs une grave erreur de conception
    • les CMS sont souvent une vraie fausse bonne solution... ils sont souvent de véritables usines à gaz et bourrés de trous de sécurité (phpbb utilise encore md5 pour ses mots de passe par exemple)
    • éviter de se donner des responsabilités dont c'est le rôle d'autres: les opérations bancaire, c'est le rôle des banques... chercher à leur prendre ce rôle, c'est juste s'exposer au attaques pour récupérer les identifiants bancaire qu'on voudrait stocker à des pseudo fins de "rendre le paiement plus simple et rapide"... y a qu'à voir le nombre de grandes enseigne qui passe un sale 1/4 d'heure en procès en dédommagement ensuite...


    si on applique ça à php et mysql:
    • oublier les connecteurs à mysql que sont mysql et mysqli... ils sont en voie d'abandon, utiliser PDO...
    • ne jamais croire ce qui vient du client ($_GET,$_POST, etc...)
    • limiter tant que faire ce peut les valeurs de type texte privilégier les valeur numériques...
    • si tu récupères des valeurs venant du client, TOUJOURS les tester et garantir une valeur que tu contrôles, ne jamais les mettre telles qu'elles dans du sql, il faut que le type soit cohérent avec celui attendu...
    • TOUJOURS échapper les chaines de caractères
    • si tu peux utilise un user sql avec que "grant execute" et des procédures stockées... ça bloquera un certain nombre de possibilités d'injection supplémentaires
    • pour les chaines de caractères, utiliser une regexp pour tester la présence de chose que tu veux interdire ou d'un format particulier (date par exemple)


    PDO te permet de t'assurer que la valeur que tu passe est du bon type...

    donc lis bien sa doc

  8. #8
    Membre chevronné Avatar de Inazo
    Profil pro
    Gérant - société de développement web
    Inscrit en
    Avril 2007
    Messages
    417
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Gérant - société de développement web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 417
    Par défaut
    Je vais rajouter une tite remarque sinon le complément est bon :

    pour les chaines de caractères, utiliser une regexp pour tester la présence de chose que tu veux interdire
    Le plus souvent utilise plutôt des regex pour tester la présence de ce que tu attends.

    Exemple classique :

    Tu organise une fête dans Paris tu as invité 1000 personnes, est-il plus simple d'avoir la liste des 1000 invités et de contrôler les identités à l'entrée ? OU est-il plus simple d'avoir les millions d'identité qui n'ont pas le droit d'entrée ?

    Ah oui et :

    PDO te permet de t'assurer que la valeur que tu passe est du bon type...
    Bien lire la documentation PDO pour l'utiliser comme il faut sinon rien ne sera protéger pour autant

    Cordialement,

  9. #9
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    OU le format voulu... tu peux chercher aussi bien ce que tu veux interdire ou autorisé ça dépend du contexte bien sur...

    et certaines fonctions de php sont plus efficace qu'une regexp par exemple pour déterminer si tu es bien face à un email par exemple

    le but est juste de s'assurer quand tu peux le faire de ce que tu rentres...

    si tu es face à du texte libre ou du code que tu dois stocker, seul l'échappement sert ou le remplacement des caractères litigieux pour le stockage en bd...

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par Ingesys Voir le message
    Bonjour,

    Ma question est donc la suivante : Y a-t-il un moyen sûr ou une méthode sure de coder en structurant son code dans différents fichiers, par exemple script principal, appelant un script où sont définies les variables, un autre les fonctions (javascirpt par ex) et un autre les instructions SQL ? ou cela n'a-t-il aucune incidence ?
    Clairement non. L'organisation des scripts et du code n'a de seul intérêt que d'améliorer la maintenance / réutilisation du code et donc d'être plus productif.
    Le "standard" actuel est de se baser sur le pattern MVC ou un de ses dérivés.

    Citation Envoyé par Ingesys Voir le message
    Deuxième question qui vient compléter la première : Afin d'éviter des intrusions, qu'est-ce qui ne doit pas circuler exactement entre un client et un serveur ? (plutôt que de décrire uniquement comment protéger l'accès aux valeurs des variables).
    Tu peux faire circuler tout ce que tu veux , c'est la façon de le faire qui compte. Concrètement tout ce qui est considéré comme sensible doit circuler en https (donc crypté). Par exemple une identification d'utilisateur doit se faire en https , sinon les identifiants et mot de passe vont circuler en clair entre le poste client et le serveur. Idem pour la création de compte , le paiement , etc ...

    Citation Envoyé par Ingesys Voir le message
    J'ai pour ma part effectué des appels de bases classiques avec les instructions INSERT et SELECt essentiellement.

    Je suis au courant pour les escapestring concernant l'appel des valeurs de la base avec $_post ou $_get, afin de protéger l'accès aux valeurs de la base, ainsi que des méthodes préparées.

    Est-ce cependant suffisant ? Le risque d'injection ne vient-il pas plutôt (ou également) de la manière de coder son PHP ?
    Pour les injections sql :
    Ne jamais faire confiance aux données venant de l'utilisateur. Même une liste déroulante que tu as défini pourra être modifié.
    Pour celà :
    - Filtrage des données avec filter_var() et/ou filter_input()- Typage des données (faire un float_val() sur un prix par exemple)
    - Requête préparées qui sont à l'heure actuelle la solution la plus sure.

    Pour l'affichage :
    Empécher toute execution de script camouflé dans des données coté client
    - Echaper les données affichées via htmlentites() ou htmlspecilchars() afin d'éviter les faille xss.

    Pour les formulaire :
    - Utiliser un token pour se protéger des failles CSRF (cross site request forgery)

    Pour conclure , quelques lectures utiles (c'est pas 300 pages )

    Guide sur les authentification :
    http://stackoverflow.com/questions/549/the-definitive-guide-to-forms-based-website-authentication/

    Gérer les injection sql :
    http://stackoverflow.com/questions/60174/best-way-to-prevent-sql-injection-in-php/
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Par défaut Framework recommandé ?
    Bonjour à tous et merci pour vos réponses fournies.

    Excusez ma réponse tardive mais j'ai été un peu surbooké ces temps-ci, et vous m'avez (à ma grande satisfaction) donné de la lecture supplémentaire, avec pas mal de liens à consulter...(lus au coup par coup ces derniers jours).

    Je me dois donc ici de faire une réponse collégiale, car répondre à chacun d'entre vous serait trop long.

    Commençons par les risques liés au réseau et à l'authentification : mon projet sera hébergé par un hébergeur de qualité (j'ai mes contacts ). Je lui fais donc confiance pour me fournir un environnement sécurisé (exit les failles du cache ARP, etc...), que ce soit au niveau infra, réseau ou système.

    Concernant la partie financière. Effectivement, c'est le travail des banques et je sais heureusement par mes fonctions passées que des organismes font cela très bien. J'ajoute d'ailleurs qu'au delà du risque mentionné sur le vol de données bancaires pour celui qui s'aventurerait à jouer le rôle des banques, il se verrait encourir une responsabilité au niveau juridique qui pourrait avoir de graves conséquences sur l'avenir de sa société.

    Concernant le hashage de données, j'ai lu personnellement que le MD5 était obsolète, et qu'il vaut mieux faire du Sha1 (merci de bien vouloir confirmer). Mon site aura une partie User et une interface Admin (comme tout bon site e-commerce). La partie admin sera sécurisée en SSL. Par contre, à lire grunk il faudrait si j'ai bien compris que le site soit intégralement en https....euh... obligé ? (ça coute bonbon tout ça...)

    Pour finir, j'ai zappé pas mal de trucs et je m'en excuse (j'ai bien intégré quoi qu'il en soit l'usage des guillemets, et bien sûr que l'utilisateur ne sera pas root), mais la soluce finale serait si j'ai bien compris d'utiliser un framework : ça éviterait les mauvaises pratiques en matière de sécurité au niveau code/base, et ça permettrait de structurer le code ou de le moduler, afin de s'en resservir pour le même projet et d'alléger les charges serveurs, ou carrément pour développer par la suite d'autres projets similaires.

    J'ai parcouru (notamment sur votre site) des messages d'utilisateurs qui comparaient les framewroks (mais c'est très subjectif), et je n'arrive pas à me décider : j'hésite entre Cake PHP, Symphony, ou Yii qui pas l'air pas mal pour ce que je dois faire. Les niveaux de sécurité ont l'air différents de l'un à l'autre (certains seulement verrouillent les failles CSRF).

    Sur l'interface d'admin j'ai néanmoins deux questions :

    Que pensez-vous du recours à un webauth ?
    Ne vaut-il pas mieux faire une table spéciale admin avec identifiant unique, que de mettre l'admin dans la table users ? ou c'est inutile ?

    Pour la gestion des tables mySQL, que pensez-vous de dbforge Studio for mysql de Devart ? L'avez-vous utilisé ? (j'ai vu la pub sur un des liens fournis).

    Merci pour vos réponses.

    J'essaierai d'être plus rapide pour répondre cette fois-ci. :-)

  12. #12
    Membre émérite

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Par défaut
    pas une remarque pour PDO ( j'ai lu en travers ) ?

    avoir un endroit ou toutes les transactions bdd vs clients sont OK sur un serveur donné avec login mdp

    a l’époque, les plus grands pirates étaient des employé des entreprises ???

    nan, faut pas te faire de bile, les personnes qui peuvent te pirater :

    ton provider : ( des personnes bossant chez eux pas tres reglos )
    ton ami : il vient chez toi et se sert de ton ordi
    ton voisin : po de bol c'est un pirate, il capte tes mots de passe par http
    ton client : ??? po sur qu'il ai que çà à faire

  13. #13
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    si si j'en ai parlé

    tu as été trop de travers...

  14. #14
    Membre chevronné Avatar de Inazo
    Profil pro
    Gérant - société de développement web
    Inscrit en
    Avril 2007
    Messages
    417
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Gérant - société de développement web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 417
    Par défaut
    Bonjour,

    Ceci n'est pas vrai :

    mais la soluce finale serait si j'ai bien compris d'utiliser un framework : ça éviterait les mauvaises pratiques en matière de sécurité au niveau code/base
    Utiliser un framework ne protège pas des mauvaise pratiques de code et de sécurité. Encore faut-il utiliser ces outils de manière correct tout comme pour ma remarque sur PDO, certain l'utilise en disant "j'ai PDO je risque rien !" alors qu'il laisse des failles SQL béante du fait de la mauvaise utilisation des fonctions.

    La réciproque est vrais pour les CMS ce n'est pas parce que vous utilisez un CMS que votre site/application est une passoire.

    HTTPS partout si vous avez les moyens why not... Après il y a SSL et SSL ceux sans assurance en cas de problème ou avec des assurances ridicule et les certificats capable de couvrir plus de 500k € d'assurances.

    Cordialement,

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

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

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par Ingesys Voir le message
    Concernant le hashage de données, j'ai lu personnellement que le MD5 était obsolète, et qu'il vaut mieux faire du Sha1 (merci de bien vouloir confirmer).
    Le md5 est obsolète c'est certain. Le SHA à tendance à être déprécié aussi à cause des nombreuses table de correspondance (rainbowtable) disponible. Il est moins facile à bruteforcer, mais pas forcément idéal.

    La mode en ce moment c'est bcrypt. Un algo que l'on peux faire évoluer dans le temps avec un simple paramètre au fur et à mesure que les machines deviennent plus puissante.
    Il à la particularité d'être très lent (comparé aux autres) et donc d'être très difficile à brute forcer. De plus chaque mot de passe est salé avec un sel aléatoire et un même mot de passe ne donnera pas 2x le même hash , du coup ça exclu les tables de comparaison.
    Un exemple d'implémentation avec Blowfish : https://github.com/grunk/Pry/blob/ma...rypt.class.php

    Une lib de référence dans le domaine en ce moment est phpass (ouais c'est pas glorieux comme nom ^^ )

    Citation Envoyé par Ingesys Voir le message
    Par contre, à lire grunk il faudrait si j'ai bien compris que le site soit intégralement en https....euh... obligé ? (ça coute bonbon tout ça...)
    J'ai pas dis tout le site , j'ai dis les données sensibles
    Que quelqu'un puisse intercepter les données du panier n'a aucune espèce d'importance , par contre les identifiants (à l'authentification) ça c'est génant.
    Le plus simple est de regarder comment la problématique est gérée par les gros site de ecommerce.

    Un certificats ssl c'est valable pour tout ton domaine , donc une page ou un site c'est pareil. Ça te coûtera juste un peu plus cher en bande passante si jamais tu la paye.

    Citation Envoyé par Ingesys Voir le message
    mais la soluce finale serait si j'ai bien compris d'utiliser un framework : [...] et d'alléger les charges serveurs.
    Un framework ça fait tout ce que tu veux sauf alléger la charge serveur. Certain du genre de symfony sont même incapable de faire tourner un site en production sans un minimum de cache d'opcode. Une fois configuré correctement ils peuvent cependant être performants.


    Ne vaut-il pas mieux faire une table spéciale admin avec identifiant unique, que de mettre l'admin dans la table users ? ou c'est inutile ?
    En général on découple complètement le backoffice (admin) du reste. Ainsi les utilisateurs , les sessions ... sont complètement différents. Il faut considérer l'admin comme un application à part. C'est pour moi le plus sur.


    Pour la gestion des tables mySQL, que pensez-vous de dbforge Studio for mysql de Devart ? L'avez-vous utilisé ? (j'ai vu la pub sur un des liens fournis).
    Mysql fournit MysqlWorkbench qui marche très bien
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  16. #16
    Membre éprouvé Avatar de redoran
    Homme Profil pro
    Développeur-Amateur
    Inscrit en
    Juin 2010
    Messages
    1 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur-Amateur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 346
    Par défaut dents de la mer
    une fois connecté on est devant ce que j'appel les dents de la mer ou fredy..
    y'a toujours de nouveaux risques donc sécurité et menace évolues en parallèles (maitrise de risque).
    donc selon certaines publication on démontré que les motifs d'agressions sont dues:
    1. pour le gain (lucratif).
    2. fraude.

    donc comment définir un niveau de sécurité optimal ?
    là la sécurité doit étre pensée durant tous le cycle de développement et non a la fin du cycle.
    en générale la sécurité passe :
    développeur N° 1 !!!!!!! ( cahier de charge , missions partagées.... , formation au développement sécurisé)
    l’hébergeur ( moyen humain est matériel).
    serveur ( soft + présence d'autres applications augmentant le risque).
    application web:
    gestion de l'authentification ( comment?).
    les injections (bdd , LDAP , cross site scripting).....
    tous cela envoi vers les bonnes pratiques !!!!!! (proactive ou par prévention...)
    suivre les nouvelles du piratage...
    un avis d'un expert....
    donc la liste est langue.....
    je ne c'est pas s'il existe un référentiel sur la sécurité dans le forum !!!

  17. #17
    Nouveau membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Juillet 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Juillet 2012
    Messages : 8
    Par défaut Config Front /Back
    Bonjour,

    Merci pour le lien sur Workbench grunk ! Je ne connaissais pas...

    Je précise naturellement que j'ai simplifié la chose sur les rapports Front / Back. J'ai un peu trop la tête dans le guidon au niveau code, pour m'être interrogé sur la structure de mon site.

    En fait, mon challenge perso c'était de me prouver que je pouvais coder en PHP / MySql pour obtenir ce que je voulais. Donc, j'ai un peu mis la charrue avant les boeufs...

    J'en profite pour apporter ici ma petite contribution :

    La structure au niveau environnement idéale pour un site e-commerce c'est DEV/ PPRD / PRD (développement, pré-production, production).

    Seules les PPRD et PRD ont chacun un Front et un Back, ce sont en général deux copies identiques, et on fonctionne par réplication -on pousse donc de la DEV vers la PPRD ce qui évite de pousser n'importe quoi en PROD, lors de modifications apportées au site (que ce soit sur l'aspect du site ou sur le contenu), ce qui peut faire planter le site (si, si c'est déjà arrivé). Dans ce cas là, les accès Admin ne se font qu'en PPRD. Seul l'hébergeur a des accès en PROD. Quant à la DEV c'est ici mon PC en localhost (ça c'est réglé).

    Le serveur Front comporte Serveur Apache, Php, MysqL, et les applications Web. Le serveur de Back comporte les données de ces applications et la base SQL à proprement parlé (ça évite pas les injections, mais ça évite de se faire pomper la base "en dur").

    Maintenant je suis pas Crésus non plus, et je vais évidemment me contenter d'un structure Front-Back simple. A savoir s'il ne faut pas plusieurs instances de MySQL ou un MYSQL en Front et un en Back, là j'avoue que je sèche. Tout dépend de se qu’accepte le fichier My.ini comme config (datadir1, datadir2,...) ou un My1.ini, My2.ini. Honnêtement j'ai jamais essayé.

    Il faut donc à mon avis deux bases séparées avec des tables communes (produits, ventes, notamment). Et on fonctionne par réplication de tables communes du Back vers le Front par des simples Cron ou MAJ manuelles.

    Bref...tout ça c'est de la sauce hébergeur et je compte sur leur savoir pour me pondre un truc au mieux au niveau sécurité.

    Pour en revenir au Framework, à ce que j'en ai lu, pour les plus connus et les plus récents d'entre eux, normalement c'est verrouillé au niveau attaques en tout genre, et ça permet de pas trop mettre le nez dans le code. Après, à vous entendre, si c'est pour se taper des vérifs à tout va, alors ça vaut peut-être pas le coup.

    Pour le SSL, oui, c'est affilié à un nom de domaine. Maintenant rien n'empêche une restriction à l'usage de la partie Admin...mais bon pourquoi se priver dans ce cas...

    Merci pour vos précisions sur MySQL. Encore une fois, j'ai toujours vus ça globalement.

Discussions similaires

  1. [MySQL] Sécurité contre les injections SQL ?
    Par kopros2 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 17/06/2014, 19h48
  2. [MySQL] Sécurité PHP/MySQL insert/affichage
    Par thibaud28 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 07/03/2010, 20h22
  3. Connaissez-vous un CMS connu en "PHP-MYSQL/ASP-SQL" du type "EBP / Quadratus" ?
    Par Apfel dans le forum Autres Solutions d'entreprise
    Réponses: 0
    Dernier message: 01/09/2009, 21h18
  4. Sécurité contre les injections SQL
    Par Generation-Web dans le forum Langage
    Réponses: 2
    Dernier message: 27/11/2008, 14h17
  5. [Sécurité] protections php pour XSS, injections SQL, etc
    Par nintendoplayer dans le forum Langage
    Réponses: 1
    Dernier message: 20/03/2008, 08h57

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