protéger son site web des injections

Nouveau WRInaute
Bonjour :D ,


Voici un sujet sur lequel j'ai un peu de mal...mais bon, sans doute saurez-vous m'aider.

Sur un de mes sites, et sur cetaines pages de ce site, j'ai mis en place un controle d'url à 100%... dès qu'une url est hors variables de la base de données, un mail m'est envoyé me précisant l'url incriminée.

Ainsi, en 2 ou 3 mois j'ai collectionner des url "exotiques". Dans la pratique, un navigateur appelle une de mes pages en utilisant la variable figurant dans l'url, sauf que comme valeur de cette variable, il met sa petite salade perso...

Donc je ne site pas ici les url complète, simplement, les valeurs "exotiques" données a la variable normale de mes pages:

=ht*p://amyr........txt

Ici, j'ai simplement remplacé "http" par "ht*p".

Ma question est générale:
Que faire pour gérer au mieux ce genre de truc?

Pour ma part, j'aimerais faire un controle à 100% sur toutes mes pages.
Hors par exemple, à l'heure actuelle si je mets une ancre sur mes pages protégées, elles sont pas acceptées par mon algo de controle et renvoie l'internaute à l'index.

Php 5 n'apporterait-il pas des fonctions spéciales pour éviter ce type de problème.

Voila, donc je poste ce message pour tenter de faire un tour d'horizons des mesures qu'on peut prendre.

Je note au passage que y en meme un qui injecte apparemment de l'hexa décimal dans l'url... si je dois commencer à controler des paramètres de variables qui mélangent caractère normaux et hexa, je suis peut-etre pas sorti de l'auberge...

Bonne journée
bloubi
 
WRInaute passionné
Si ta variable en question ne doit pas contenir http, la vérification est vite faîte !

Si maintenant, tu te sert d'un include pour faire une pseudo frame, tu risques :

:arrow: Rog va te rentrer dans le lard si il tombe sur ce topic.
:arrow: Forcément, tu risque d'inclure du code PHP qui s'exécutera sur TON serveur !!

Si vraiment, tu ne veux pas (car on peux toujours faire autrement), il faut que tu vérifie que le fichier appelé est bien présent sur ton serveur.
 
WRInaute occasionnel
Hmm...
Ces fichiers textes contiennent du code php qui est interprété en général sur la machine à hacker. Il existe 2 types de fichiers :
- ceux qui testent s'ils peuvent faire quelque chose sur le serveur
- ceux qui contiennent une interface complète pour gérer le serveur hacker depuis le site attaqué
Moi je te conseille :
1- Installe Crawltrack: sa nouvelle version permet de bloquer certaines attaques de ce genre, mais ce n'est pas un outil miracle, c'est une première protection.
2- Dans TOUS tes include de fichiers, effectues un test de présence sur ton serveur (comme vient de le dire medium :
Code:
if(file_exists($_GET['ta_variable']))
    inclue('repertoire/'.$_GET['ta_variable'].'extension');
else
{
    //traitement de la tentative d'injection : enregistrement logs BDD, mail, blocage de l'ip, etc...
}
Ce ne sont que des solutions de base, elles ne constituent en rien une protection absolue, mais c'est un bon début je pense.
A bon entendeur.
 
Nouveau WRInaute
Bonjour,


Non, ma variable n'a pas besoin de contenir http.
Qu'est-ce qui ne va pas dans mon message, pour que rog me tombe dessus?
(j'ai enlevé les adresses "exotiques"... si c'est ça qui gène ....)

merci d'avance
bloubi
 
WRInaute accro
bloubi a dit:
Ainsi, en 2 ou 3 mois j'ai collectionner des url "exotiques". Dans la pratique, un navigateur appelle une de mes pages en utilisant la variable figurant dans l'url, sauf que comme valeur de cette variable, il met sa petite salade perso...

Donc je ne site pas ici les url complète, simplement, les valeurs "exotiques" données a la variable normale de mes pages:

=ht*p://amyru.h18.ru/images/cs.txt?
[...]

Je ne suis pas sûr de comprendre... Que devraient contenir ces variables, et qu'en fais-tu? Si ce sont des choses qui devraient sortir de ta base de données, je ne comprends pas pourquoi tu balades l'URL plutôt qu'un ID de la dite base de données. Si tu n'attends pas des URLs mais des valeurs bien définies (des nombres, une sélection dans une liste...?) tu peux facilement valider, et il n'y a pas de problème. Si tu attends bien des URLs quelconques, qu'en fais-tu? Si tu ne fais que les stocker et les afficher, c'est plus un problème "éditorial" qu'autre chose. Si tu les utilises pour aller y chercher des choses, l'URL elle-même ne devrait pas être plus problématique que ça, et le contenu, ben ça dépend de ce que tu attends et de ce que tu en fais.

Bref, ça manque pas mal de détails pour ne serait-ce que comprendre le problème initial (et le rapport avec une injection de code, qui n'a pas grand chose à voir avec ça a priori).

En fait, je ne suis même pas sûr qu'il y ait effectivement un problème! :-)

Jacques.
 
WRInaute passionné
bloubi a dit:
Bonjour,


Non, ma variable n'a pas besoin de contenir http.
Qu'est-ce qui ne va pas dans mon message, pour que rog me tombe dessus?
(j'ai enlevé les adresses "exotiques"... si c'est ça qui gène ....)

merci d'avance
bloubi

lol Désolé de t'avoir fait peur... je n'avais pas vu que tu étais nouveau ici.

Rog est un spécialiste de la sécurité, et il donne de très bonne réponses, mais malheureusement, parfois, quand c'est une évidence pour lui, il les assène assez durement.

Donc quand on le connaît pas, on pense qu'il nous agresse :wink:
 
WRInaute passionné
bloubi a dit:
Bonjour,


Non, ma variable n'a pas besoin de contenir http.
Qu'est-ce qui ne va pas dans mon message, pour que rog me tombe dessus?
(j'ai enlevé les adresses "exotiques"... si c'est ça qui gène ....)

merci d'avance
bloubi

Dans ce cas, si c'est pas pour un include, tu n'a pas vraiment besoin de t'inquiété ; à moins que je me trompe, au pire ça devrait affiché une erreur 404 non ??

J'ai compris ! 8)

Tu reçois un e-mail en cas de problèmes ; moi aussi, et j'ai eu ce genre de soucis dont tu parles.

Si ton site est bien fait, et que tu n'a pas d'include pour les url passé en variable, tu n'a pas vraiment à t'inquiété. Au pire si cela se produit trop souvent et que cela te dérange, tu peux interdire l'accès via htaccess.

Si $_server['REQUEST_URI'] contient variable id=http(n'importe quoi), tu refuse l'accès
Code:
SetEnvIfNoCase Request_URI id=http(.*) ban
<Files ~ "^.*$">
order allow,deny
allow from all
deny from env=ban
</Files>

Code à confirmer par un pro, mais je pense que cela devrait être bon
 
Nouveau WRInaute
Bonjour et merci de votre aide,


pour répondre à jcaron, et pour expliquer un peu plus, je dirais ca:
Comment protéger son site?
Dans la pratique c'est très dur de trouver quoi faire, pour contrer quoi., j'en sais meme trop rien... Je lance le sujet car je suis une crasse dans le domaine, et que je sais meme pas vraiment ce qui est important...

Moi, sur certaines de mes pages dynamiques, j'ai mis un algo qui liste les valeurs possibles de ma variable qui se trouvent dans ma base de donnée. J'en fais un tableau... Si la valeur de la variable demandée par l'internaute ne figure pas dans mon tableau:
* je m'envoie un mail pour dire "l'url machin truc a été tapée par un internaute"
* je renvoie l'internaute sur la page index.html du site.

Voyez que j'ai fait un truc pas mal, puisque c'est mieux que rien... Je sais qu'on peut faire du mal à un site grace aux injections... donc j'ai fait mon algo dans ce sens. Mais d'ailleurs, à part rediriger l'internaute sur la page d'index, y aurait-il quelque chose de plus efficace à faire?

D'ailleurs, existerait-il une vrai "how to" pour débutant dans la sécurité internet?

Il me semblait par exemple de php5 Apportait des fonctions innovantes,non?
Je vais essayer de comprendre le code de medium 69.

a+
Alain
 
WRInaute accro
bloubi a dit:
Comment protéger son site?
Dans la pratique c'est très dur de trouver quoi faire, pour contrer quoi., j'en sais meme trop rien... Je lance le sujet car je suis une crasse dans le domaine, et que je sais meme pas vraiment ce qui est important...

Encore une fois, tout dépend de ce que tu fais des données. Les problèmes d'injection de code (comme évoqué dans le sujet), c'est lié à des problématiques d'exécution de code généré dynamiquement dont certains bouts pourraient ne pas vraiment faire ce que tu veux.

L'exemple classique c'est en SQL: tu as une requête du genre:
(attention: mauvais code à ne pas utiliser) "SELECT * FROM matable WHERE colonne=$valeur". Le résultat c'est que si $valeur est un paramètre passé par l'utilisateur à ton script, et que tu ne le vérifies pas de façon assez stricte, l'utilisateur peut passer des choses pas très sympa, puisque ce sera bêtement collé dans la requête, qui peut soudainement avoir un effet très différent.

La solution à ça c'est (dans la plupart des langages, je ne sais pas pour PHP), d'utiliser des placeholders ("?" ou ":foo" ou "$1" suivant les cas) et de passer les paramètres séparément, l'API utilisée se chargera de faire le "quoting" nécessaire pour s'assurer que les valeurs ne peuvent pas être interprétées autrement que des valeurs (et pas du code). Sinon il y a la possibilité de faire la même chose "soi-même" avec les fonctions de quoting fournies dans les API, mais je conseille quand même très fortement la première option.

De la même façon, dans les languages interprétés (et assimilés) qui ont des fonctions du genre "eval" qui permettent d'interpréter du code généré dynamiquement, on peut avoir des mauvaises surprises aussi. A la base, c'est à éviter très sérieusement, et sinon il faut vraiment valider très strictement les variables utilisées pour composer le code dynamique, ou faire du quoting à tour de bras, mais il est souvent difficile de ne pas oublier un cas tordu.

Similairement, les appels du type "system" qui invoquent des shells sont extrèmement dangereux. Si tu fais system("rm /chemin/a/la/con/$fichier"), rien n'empêche l'utilisateur d'envoyer un nom de fichier contenant des ".." ou encore des "nomdefichier ; instruction_qui_tue". Pareil, à éviter au maximum (utiliser les API directement, c'est nettement mieux), ou valider très strictement. Quoter un appel à un shell sans rien oublier ça relève de l'exploit.

Bref, le problème n'est pas ce que l'utilisateur t'envoie, mais ce que tu en fais. Une URL, en soi, ça n'a rien de dangereux, et si la seule chose que tu fais avec c'est de les afficher, ça peut juste être une forme de spam, auquel cas le problème est plus éditorial qu'autre chose.

bloubi a dit:
Moi, sur certaines de mes pages dynamiques, j'ai mis un algo qui liste les valeurs possibles de ma variable qui se trouvent dans ma base de donnée. J'en fais un tableau... Si la valeur de la variable demandée par l'internaute ne figure pas dans mon tableau:
* je m'envoie un mail pour dire "l'url machin truc a été tapée par un internaute"
* je renvoie l'internaute sur la page index.html du site.

Visiblement tu attends effectivement une URL, mais cette URL devrait déjà être dans ta base de données. Pourquoi passer l'URL? Passe l'ID de l'URL dans ta base de données, et va la rechercher de l'autre côté. Ca te fera des URLs (de tes pages) plus courtes, plus lisibles, avec moins de possibilité de manipulation, pas de problème d'URL-encodage, etc.

Hope that helps,

Jacques.
 
WRInaute passionné
bloubi a dit:
Bonjour Médium69

J'ai essayé ton code dans un htaccess dans un sous-repertoire, ca à pas l'air de marcher:

http://www.monsite.com/access/index.php ... //toto.com

la page s'affiche... voici mon htaccess

SetEnvIfNoCase Request_URI id=http(.*) ban
<Files ~ "^.*$">
order allow,deny
allow from all
deny from env=ban
</Files>

sachant que j'ai déjà un htaccess à la racine du site.

merci
a+

Là, ça dépasse mes compétences... J'aurais dit un QUERY_STRING, mais ce n'est pas bon non plus :(
 
WRInaute passionné
bonjour boubli,

sache d'abord que tu ne pourra jamais empécher quiconque d'essayer d'accéder à to site avec des URL exotiques.

Pour te protéger tu dois simplement respecter quelques règles simples:

1 - Ne jamais utiliser une variable passée dans l'url directement pour quoi que ce soit (include, accés BDD). Même un simple "echo" sur l'écran peut être risqué.

2 - tu dois filtrer le contenu de ces variables. Tu peux utiliser pour cela des fonsctions PHP du genre strip_tags par exemple pour supprimer toute balise html. Mieux, tu teste chaque variable avec une expression régulière.
(Si tu me dis que c'est impossible, alors je pense qu'il te faut repenser tes format d'url!) et tu renvois une erreur 404 dés que cela ne correspond pas.

3 - Tu mets en place l'url rewriting pour au moins masquer le nombre et les noms de tes variables.

En ce qui concerne l'envoie d'un mail lorsqu'une erreur est détectée, ben ou alors tu as une boite mail de 100 Go ou bien ton trafic est trés faible :wink: Tu as un fichier de logs qui t'apprendra tout ça tout aussi bien sans plomber ta boite mail et/ou ta bande passante qui en plus, garde la trace de tout contrairement à ta solution. Tu peux même recevoir un rapport par mail tous les jours avec logwatch si tu aime les mails :D
 
WRInaute passionné
C'est marrant, mais depuis que j'ai posté sur ce topic, j'ai eu un surcroît de tentative de ce genre d'attaque ! :P

WRI serait donc aussi fréquenté par des corsaires :?: :lol:
 
Nouveau WRInaute
Bonjour :P ,


Je voulais vous remercier pour vos idées...
Je viens de passer un moment à regarder le site crawltrack, notamment la démo, ou l'on voit les tentatives d'injection de code et injections SQL. Déjà cela donne une idée du truc...

Par contre encore installer un logiciel juste pour détecter des http et des % dans les url, je trouver que c'est un peu trop... non?

Il y a un détail que je ne comprend pas. Y a-t-il un risque d'injections sur une vrai page html (100% statique)?

Jcaron, tu parle de placeholder et d'api... je sais pas ce que c'est...

Par contre dites moi si je me trompe, mais la fonction mysql_real_escape_string() existe à partir de php5 , non?

Je souhaite garder du "texte" dans mes url pour améliorer le référencement.


Merci
bloubi
 
WRInaute accro
bloubi a dit:
Jcaron, tu parle de placeholder et d'api... je sais pas ce que c'est...

Une API c'est une interface de programmation. Genre l'API de mysql ça va être toutes les fonctions qui permettent de faire des requêtes mysql.

Les placeholders ("les gardeurs de place") c'est un moyen de séparer la commande elle-même des valeurs. Dans une requête du type "SELECT * FROM matable WHERE id=12", on sépare donc en "SELECT * FROM matable WHERE id=?" et on passe le 12 séparément. Quand la valeur est en "dur" comme ça ça ne change pas grand chose, mais quand elle vient d'une variable ça permet de faire en sorte que l'API (les fonctions utilisées pour exécuter cette requête) s'assurent que la valeur est bien "escapée", en s'assurant que les ' et autres \ ne sont pas passés tels quels (ce qui permettrait de faire de l'injection).

Les placeholders ça existe par exemple dans les API DBI en perl, mysqli et PDO en php (5+). En php 4 à vue de nez ça n'existe pas pour mysql (mais comme je n'utilise jamais php je peux me tromper), donc on est obligé d'utiliser mysql_real_escape_string à chaque coup, ce qui est évidemment facilement oublié :-(

bloubi a dit:
Par contre dites moi si je me trompe, mais la fonction mysql_real_escape_string() existe à partir de php5 , non?

La doc dit que ça existe à partir de la 4.3.0. Avant (à partir de la 4.0.3) il y avait mysql_escape_string mais il a des problèmes de charset, dixit la doc.

bloubi a dit:
Je souhaite garder du "texte" dans mes url pour améliorer le référencement.

Euh, si c'est dans des paramètres genre url=machin, je doute que ça ait beaucoup d'effet... Ceci dit, comme je ne sais pas du tout quel est ton site, et ce que tu fais avec tout ça, c'est du pur wild guess...
 
WRInaute passionné
chtipepere a dit:
2- Dans TOUS tes include de fichiers, effectues un test de présence sur ton serveur (comme vient de le dire medium :
Code:
if(file_exists($_GET['ta_variable']))
    inclue('repertoire/'.$_GET['ta_variable'].'extension');
else
{
    //traitement de la tentative d'injection : enregistrement logs BDD, mail, blocage de l'ip, etc...
}
Ce ne sont que des solutions de base, elles ne constituent en rien une protection absolue, mais c'est un bon début je pense.
A bon entendeur.

Si tu penses avoir protégé ton site en procédant de cette façon, alors j'ai une TRES mauvaise nouvelle pour toi.
file_exists() accepte les url distantes (donc celle du spammeur).

bloubi, ton site ne fera pas long feu si tu n'apprends pas quelques notions de base de sécurité. Le conseil qu'on t'a donné (utiliser /site.php?id=925 au lieu de site.php?url=/mapage-truc.php ) est le seul réellement efficace de ce topic. Et encore, à condition que tu utilises mysql_real_escape_string() (ou tout simplement... intval() ) sur ce paramètre $_GET['id']

Toutes les autres inclusions à base de ?url=... sont risquées.

Si tu veux avoir les mots clefs dans ton url, rien ne t'empeche de faire : /site.php?id=925-mon-titre-super-intéressant
Et tu fais un coup de intval() sur le paramètre pour récupérer juste le "925". C'est une solution que tu peux voir à l'oeuvre ici par exemple :
-http://www.grandes-ecoles-paysdeloire.com/grandes-ecoles-pays-de-la-loire.php?ecole=1-CENTRALE%20NANTES

Tu n'as pas répondu à la seule vraie question importante qui nous aurait permis de te conseiller en détail : que fais-tu sur ta page qui reçoit le paramètre url ? que fais-tu de ce paramètre ?

P.
 
Nouveau WRInaute
Bonjour Dj_Apx,


Je te remercie de ton astuce avec un id dans la valeur de la variable.
C'est vraiment très "astucieux"....Je vais voir si je peux appliquer ca sur mon site... Je pense que ca vaut le coup d'essayer...

En fait j'ai 3 ou 4 pages dynamiques qui fonctionnent sur le meme principe:
j'utilise la variable de l'url (après vérification) pour après faire une requete du genre:
SELECT * FROM table WHERE champ = '$variable_de_l_url'

Ainsi, je peux remplir ma page avec les infos qui correspondent avec ce qu'attends l'internaute...

Un truc sympa: avec mon nouvel hébergeur, j'ai pu créer des accès à la base de donnée avec de droits modulés, dont un accès en lecture seule.

merci
bloubi
 

➡️ Offre MyRankingMetrics ⬅️

pré-audit SEO gratuit avec RM Tech (+ avis d'expert)
coaching offert aux clients (avec Olivier Duffez ou Fabien Faceries)

Voir les détails ici

coaching SEO
Discussions similaires
Haut