8796 sujets

Développement web côté serveur, CMS

Pages :
Bonjour tout le monde,

J'ai récemment mis en ligne un site en version beta dirons-nous et je n'ai pas assez sécuriser mes formulaires, j'ai donc une horde d'apprentis hackers qui tentent de m'ennuyer depuis.

Aujourd'hui, un type a rempli un de mes forms où je n'avais pas mis de contrôle sur le champ "Téléphone", du coup le petit malin a essayé d'entrer ça :

1 declare @x varchar(99) set @x=0x77616974666f722064656c61792027303a303a323027 exec(@x)--



Ma question est simple : vous savez ce qu'il a essayé de faire ?
Ce type de language ne me dit rien...

Mon site tourne sous un serveur Linux.

Merci.
Salut,

le langage est du SQL et cette attaque par injection (nihaorr1) ne concerne qu'ASP (sur IIS). Smiley cligne

Plus d'infos à cette adresse ou à celle-ci.


Skoua a écrit :
je n'ai pas assez sécuriser mes formulaires
C'est quand même un minimum d'utiliser mysql_real_escape_string dès que tu communiques avec ta base et htmlspecialchars dès que tu réaffiches une variable ! Smiley vieux Smiley langue
Modifié par Heyoan (05 Jun 2009 - 18:22)
Hello,

J'en profites pour poser un petite question de sécurité, me mettant au php et comme a indiqué Heyoan, j'utilise mysql_real_escape_string et htmlchars pour protéger mes scripts mais comme dans les bouquins ils ne parlent pas trop de sécurité...

J'aimerai savoir s'il y a d'autres recommandation pour éviter de faire le lapin de 6 semaines quand mes scripts seront en ligne, en sachant que mes pages sont en dur donc pas de pages gérées par les variables _get via les includes() (ça m'enlève déjà un problème Smiley smile ).

@+
Hoy !

AspiGeek a écrit :
J'aimerai savoir s'il y a d'autres recommandation pour éviter de faire le lapin de 6 semaines quand mes scripts seront en ligne
Houlà ! Voilà bien un sujet dont on ne fait jamais le tour ! Smiley lol

J'aurais tendance à commencer en disant qu'aucune protection n'est fiable à 100% (histoire de mettre dans l'ambiance) ne serait-ce que parce que ça peut venir du paramétrage de ton hébergeur (register_globals à on...) ou du comportement des internautes (je me connecte sur ton site depuis un ordinateur public et je ne me déconnecte pas...) ou encore d'autre chose dont je ne connais même pas l'existence ! Le moins risqué est encore de ne pas dépasser un pagerank de 1 (0 c'est encore mieux Smiley ravi ) et de ne pas utiliser d'outils dont les sources sont publiques (la seule fois où je me suis fait hacker cela venait d'une faille de sécurité de PHPBB).

Ensuite je dirais que le niveau de sécurité à atteindre est vraiment variable : il n'est pas le même pour un formulaire de contact, pour un forum, pour un formulaire d'achat en ligne ou pour un formulaire de connexion au ministère de la défense... D'ailleurs si cette notion est vraiment importante on fait appel à un prestataire.

Donc après cette introduction je ne vais te parler que de ce que je connais à mon petit niveau (le B.A.BA quoi) :
* pour éviter les injections SQL : mysql_real_escape_string
* pour éviter le cross site scripting (ou XSS) : htmlspecialchars
* côté paramétrage beaucoup d'hébergeurs laissent par défaut des valeurs qui risquent de poser problème mais qui, s'ils étaient changés, empêcheraient (ou en tout cas gêneraient) le bon fonctionnement de beaucoup de "vieux" sites. Par contre ils permettent en général de les modifier pour son site en passant par .htaccess ou autres moyens (sur OVH je mets à off REGISTER_GLOBALS, MAGIC_QUOTES et SESSION_USE_TRANS_SID).
* autant que possible préférer les versions les plus récentes de PHP (6 est mieux que 5 qui est mieux que 4...)
* je ne sais pas comment c'est techniquement possible mais on peut intercepter les variables en clair au moment où elles sont transmises donc pour des données vraiment sensibles (genre carte bleue) ça ne coûte rien d'utiliser SSL (uri commençant par https://...)
* pendant la phase de développement on a besoin du plus d'infos possibles (warnings, utilisation de mysql_error...) mais une fois en ligne il ne faut rien dévoiler du tout : error_reporting(0);
* il existe une forme d'attaque de formulaires de connexion (brute force) qui consiste à essayer en automatique une foultitude de couples login/password : plusieurs solutions comme ne pas autoriser une nouvelle tentative avant un certain délai ou limiter le nombre d'essais possibles pour une IP donnée, etc.
* limiter la durée de vie des cookies de sessions (un exemple sur developpez.com)
* euh... bon ben là tout de suite je ne vois plus ! Smiley murf

Un peu de lecture :
* http://fr.php.net/manual/fr/security.php
* http://www.phpsecure.info/v2/.php
* une pitite recherche Google (pour rire)


Edit: j'oubliais :
* les mots de passe ne doivent jamais être en clair (cookies, bdd, et même code php au cas où il y aurait un plantage serveur et que le code soit affiché en clair -bon... c'est quand même peu probable-).
* ne jamais faire confiance à ce qui a été saisi dans un formulaire et toujours s'attendre au pire (pour 1% à cause des hackers et pour 99% à cause des "lubies" des internautes). Smiley ravi
Modifié par Heyoan (05 Jun 2009 - 22:02)
Merci pour toutes ces précisions Heyoan, c'est sympa. Smiley smile

Je n'ai pas pensé à regarder coté serveur mais avec toutes tes pistes j'ai matière à recherche, mais quand on voit des "gros sites" se faire attaquer et pirater ça ne me rassure pas trop surtout lorsque ces sites sont fait par des professionnels.

Mais bon je crois que je vais développer mon site pépère et après je me payerai le luxe d'engager un hacker pour vérifier tout ça Smiley lol

Merci encore pour les infos !

@+
AspiGeek a écrit :
quand on voit des "gros sites" se faire attaquer et pirater ça ne me rassure pas trop surtout lorsque ces sites sont fait par des professionnels.
Ben comme je disais sous forme de blague la meilleure sécurité est encore d'être anonyme parmi les anonymes (même si ce n'est pas le but du jeu).

AspiGeek a écrit :
et après je me payerai le luxe d'engager un hacker pour vérifier tout ça
C'est une bonne idée puisque les spécialistes de la sécurité sont majoritairement d'anciens hackers !

Et sinon j'avais oublié :
AspiGeek a écrit :
en sachant que mes pages sont en dur donc pas de pages gérées par les variables _get via les includes()
C'est clair mais comme c'est une des grandes forces de PHP tu t'y mettras un jour ou l'autre ! D'ailleurs ça me fait penser qu'il existe plusieurs fonctions avec lesquelles il faut être prudent : par exemple include($_GET['page']) serait un peu déconnant si on ne fait aucun test avant...
Merci pour ta réponse Heyoan, je ne savais pas que SQL pouvait avoir cette tronche-là (faut dire que j'y connais pas grand chose pour le coup).

J'utilise en effet les deux fonctions dont tu as parlé lorsque je communique (INSERT) avec ma db, mais en l'occurence c'est juste un formulaire qui envoie un mail donc ça ne me dérangeait pas outre mesure.

@ Aspigeek : pour tes problèmes de sécurité, tu peux aussi souscrire à un abonnement McAfee pour ton site, en plus d'avoir un logo (moche) à ajouter sur ton site qui indiquera à tes visiteurs qu'aucun hacker ne pourra pirater le mot de passe de son frigo, tu seras mieux positionné sur google (aux USA) et surtout McAfee teste ton site et t'explique dans un back office les failles (côté client et serveur) qu'il a pu trouver, te permettant ainsi d'améliorer la sécurité sans trop chercher toi-même.

Par contre, je crois que ça coute la bagatelle de 40 dollars par mois, mais si la sécurité est vraiment un souci pour toi ça devrait pouvoir t'aider.
Heyoan a écrit :

[...] par exemple include($_GET['page']) serait un peu déconnant si on ne fait aucun test avant...


Tout à fait, de même que $_GET['nomDeFichier'] ou encore $_POST['nomDeFichier'].

Heyoan a écrit :
* je ne sais pas comment c'est techniquement possible mais on peut intercepter les variables en clair au moment où elles sont transmises donc pour des données vraiment sensibles (genre carte bleue) ça ne coûte rien d'utiliser SSL (uri commençant par https://...)


Pour compléter un petit peu, même si je ne suis pas un pro dans ce domaine, c'est possible en faisant du ARP Spoofing sur un réseau (WiFi, LAN...). Un fois qu'un pirate a accès à votre réseau il peut utiliser une/sa machine en tant que passerelle qui gère les connexions entrantes/sortantes entre Internet et les ordinateurs de ce réseau.
Source : http://www.crashdump.fr/securite/arp-spoofing-arp-cache-poisoning-59/
PS : Ça fonctionne aussi sur TOR
PPS : Il faut, si je ne m'abuse, aussi faire attention que les données circulant en SSL ne sont pas utilisées dans HTTP sinon ça ne sert à rien.
Modifié par kurt11 (06 Jun 2009 - 00:23)
Heyoan a écrit :
C'est clair mais comme c'est une des grandes forces de PHP tu t'y mettras un jour ou l'autre ! D'ailleurs ça me fait penser qu'il existe plusieurs fonctions avec lesquelles il faut être prudent : par exemple include($_GET['page']) serait un peu déconnant si on ne fait aucun test avant...

En fait j'utilise déjà les includes mais je préfère ne pas trop jouer en les combinant avec les $_GET. Mes problèmes de sécurité viennent surtout du fait que je débute en php Smiley smile , une fois à l'aise il est évident que j'utiliserai cette méthode sur certains projets.

skoua a écrit :
@ Aspigeek : pour tes problèmes de sécurité, tu peux aussi souscrire à un abonnement McAfee pour ton site, en plus d'avoir un logo (moche) à ajouter sur ton site qui indiquera à tes visiteurs qu'aucun hacker ne pourra pirater le mot de passe de son frigo, tu seras mieux positionné sur google (aux USA) et surtout McAfee teste ton site et t'explique dans un back office les failles (côté client et serveur) qu'il a pu trouver, te permettant ainsi d'améliorer la sécurité sans trop chercher toi-même.

Je garde ça dans un coin de ma tête, j'irai jeter un oeil merci.
Salut,
Heyoan a écrit :
* pendant la phase de développement on a besoin du plus d'infos possibles (warnings, utilisation de mysql_error...) mais une fois en ligne il ne faut rien dévoiler du tout : error_reporting(0);

Ne rien dévoiler c'est bien, mais avec error_reporting à 0 les erreurs ne s'écrivent plus non plus dans les fichiers de logs.

Donc le mieux reste de mettre error_reporting à E_ALL | E_STRICT et dans le php.ini de mettre la variable display_errors à off. Du coup toutes les erreurs et notices s'écrivent dans le fichier php_error.log mais aucune ne s'affiche à l'écran.
Question peut-être stupide pour certains, mais : que peut tirer un pirate comme genre d'information utile d'un message d'erreur php ?
Je ne vois pas comcrètement que peut faire un pirate avec un message comme quoi un include a foiré, une variable n'existe pas ou ce genre de message...

Sinon, dans le lot des trucs à faire gaffe, on a oublié le cross request forgery (CSRF ou XSRF). C'est un genre de XSS en pire, ça par contre j'ai eu la démo.
Salut Quentin,

QuentinC a écrit :
que peut tirer un pirate comme genre d'information utile d'un message d'erreur php ?
Je dirais que c'est essentiellement lié au fait de donner le nom des tables ou même une requête complète, ce qui va donner des informations pour tenter une injection SQL. Peut-être pour d'autres raisons mais je n'en sais pas plus.

Merci pour l'info sur CSRF ou XSRF : je vais me renseigner...
Dis donc le CSRF c'est drôlement malin.

Pas simple de se protéger de ce genre de choses, ça devient presque une profession en soi...

Merci pour l'info en tout cas. Smiley smile
En tout cas depuis la lecture de cette page, ce qui remonte déjà à un certain temps, je fais un usage généralisé des jetons de validité dans pratiquement tous les GET et les POST effectuant des modifications.
En gros ça consiste à générer un hash aléatoire, qui, s'il n'est pas correct à la réception, fait invalider l'action.
QuentinC a écrit :
En tout cas depuis la lecture de cette page, ce qui remonte déjà à un certain temps, je fais un usage généralisé des jetons de validité dans pratiquement tous les GET et les POST effectuant des modifications.
En gros ça consiste à générer un hash aléatoire, qui, s'il n'est pas correct à la réception, fait invalider l'action.


Petit hors-sujet... Comment tu fais ça ? Tu génére un hash que tu mets en champ hidden dans le formulaire, ainsi qu'en session et tu checkes la concordance des deux avant d'effectuer la requete ?

Cette approche me pose des problèmes en cas de multi-tabs, j'aimerai bien avoir une idée de comment tu t'y prends.
Oui c'est exactement ça. Par contre effectivement ça peut foirer si on a plusieurs onglets ouverts à la fois, seul le jeton de la dernière page générée étant effectivement valable... mais en même temps je ne vois pas vraiment l'intérêt, donc je ne me suis pas penché là-dessus.

Plusieurs onglets en parralèle pour consulter des pages d'accord, mais pour remplir deux formulaires différents en même temps sur la même session, franchement j'ai du mal à saisir où peut en être l'utilité. Tu as un exemple concret ?
Concretement oui, quand je dois remplir/éditer "à la chaine" plusieurs pages depuis l'interface d'admin. Plutot que d'ouvrir une page, modifier la valeur, valider, ouvrir la page suivante, ça me va plus vite d'ouvrir mes 15 tabs d'un coup et de modifier les valeurs à la chaine en passant d'un tab à l'autre avec ctrl+tab mais avec cette protection je me retrouvais bloqué...

Dans une autre mesure ça me générait le même genre de probleme quand je charge un second formulaire en Ajax par dessus un formulaire existant, la valeur de la session est modifiée et mon premier formulaire ne peut plus etre validé.

Il doit y avoir moyen de régler ça en prenant en compte le timestamp lors de la génération du hash et de garder plusieurs valeurs en parallelle mais j'ai laissé tombé et je fais plutot une whitelist des champs que j'accepte d'etre modifié
Pages :