Include ? Un peu peur de la faille

Include ? Un peu peur de la faille - PHP - Programmation

Marsh Posté le 24-08-2005 à 17:36:17    

Bonjour,
 
Je fais un site. Il est assez simple mais il sera souvent visité donc j'ai un peu peur des hackers (  :pfff: ) qui s'amusent avecla faille include.
 
Bon voici a peu près mon site :
 
Une page index.php, qui contient l'HTML et qui gère les include.
 
3 pages qui viennent s'incorporer dans index.php : news.php, wars.php, team.php.
 
J'utilise le $_GET est page ( index.php?page=news par exemple ).
 
Je débute en php donc j'ai besoin d'un peu d'aide.
 
Si $_GET['page'] est vide j'aimerais rediriger la page directement vers index.php?page=news.
 
J'ai demandé de l'aide sur IRC, et un gentil op m'a dit de faire ca : $info = $_GET['page']; include($info);  et pour les liens : <a href="index.htm?page=news.php">News</a>.
 
Vous en pensez quoi ?
 
Merci,
 
RaSk

Reply

Marsh Posté le 24-08-2005 à 17:36:17   

Reply

Marsh Posté le 24-08-2005 à 17:43:42    

Moi je vois vraiment pas pourquoi tu dois te faire chier ainis...m'enfin...

Reply

Marsh Posté le 24-08-2005 à 17:46:23    


Qu'il n'y a pas beaucoup de moyens plus efficaces de créer une faille de sécurité, tu peux remercier la gentille personne qui t'a proposé ça :jap:  
 
En sécurité, l'axiome de base c'est:
Ne jamais faire confiance à une donnée venant de l'utilisateur (ou de l'extérieur en général, en fait)
 
Dans ce cas précis, la chaîne "news.php" vient de l'extérieur, tu ne peux donc pas lui faire confiance.
 
Première idée: toujours sécuriser une chaîne entrée, via addslashes et htmlentities.
Deuxième idée: ici, tu as un nombre donné de page relativement faible, utilise un switch
 

switch($_GET['page']) {
    case 'news': include('news.php');break;
    case 'team': include('team.php');break;
    case 'wars': include('wars.php');break;
    default: include('error.php');brak;
}


Ici, tu sépares clairement les données utilisées/sorties et les données rentrées, les données saisies ne présentent donc pas de risque.
 
Troisième idée: tu fais tout simplement 3 pages bien séparées dans lesquelles tu inclus les éléments communs (via readfile() si ils n'ont pas de PHP, un menu par exemple), de cette manière le problème n'est plus [:spamafote]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 24-08-2005 à 17:49:03    

Une petite vérification ne serait pas du luxe :)  
Quelque chose du genre
 
switch ($_GET['page']) {
case 'news': $info = 'news.php';
case 'wars': $info = 'wars.php';
case 'team' : $info = 'teams.php';
default: die ("oula la, mais que se passe t'il !?!?" );
}
include($info);
 
ou sinon, tu mets news.php dans le default [:proy]

Reply

Marsh Posté le 24-08-2005 à 17:52:44    

Code :
  1. if isset($_GET['page'])
  2. { if ($_GET['page']='')
  3.     include(''news.php');
  4.   else if ($_GET['page']='news')
  5.     include('news.php');
  6.   else if ($_GET['page']='wars')
  7.     include('wars.php');
  8.   else if ($_GET['page']='team')
  9.     include('team.php');
  10.   else
  11.     include('news.php'); // page par défaut si erreur
  12. }else
  13. { include($info);
  14. }


 
 
sera beaucoup plus sécurisé. Ce que t'as fait faire l'autre bonhomme est l'exemple typique de la fameuse faille du moins s'il n'y a rien d'autre pour vérifier la valeur.
 
Il ne faut jamais utiliser directement le contenu d'une valeur venant de l'extérieur sans avoir au choix :

  • vérifier son contenu (comme ici avec les if) et la validité de son contenu (par exemple si on recoit une chaine de caractére alors qu'on s'attend à avoir un nombre ;) )
  • désactiver tout élément dangereux du contenu de la variable (par exemple à l'aide d' "htmlentities()" si on affiche à l'écran le contenu de la variable


De plus, il faut toujours vérifier l'existance des variables venant de l'extérieur ou d'un autre fichier php inclus avant de s'en servir. Sinon, ca affichera une alerte si le serveur est réglé pour.

Reply

Marsh Posté le 24-08-2005 à 17:53:56    

me rapellais pas qu'on pouvait faire un switch sur des chaines de caractére en php. :D

Reply

Marsh Posté le 24-08-2005 à 17:57:20    

Comment j'vous ai grillés sur le switch [:kbchris]

mrbebert a écrit :

Une petite vérification ne serait pas du luxe :)  
Quelque chose du genre
 
switch ($_GET['page']) {
case 'news': $info = 'news.php';
case 'wars': $info = 'wars.php';
case 'team' : $info = 'teams.php';
default: die ("oula la, mais que se passe t'il !?!?" );
}
include($info);
 
ou sinon, tu mets news.php dans le default [:proy]


Sauf que je crois me souvenir que le fallthrough est actif dans les switch PHP, donc tout ce que tu vas faire c'est  

Citation :

die ("oula la, mais que se passe t'il !?!?" );


quelle que soit la donnée rentrée


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 24-08-2005 à 18:01:38    

omega2 a écrit :

Code :
  1. if isset($_GET['page'])
  2. { if ($_GET['page']='')
  3.     include(''news.php');
  4.   else if ($_GET['page']='news')
  5.     include('news.php');
  6.   else if ($_GET['page']='wars')
  7.     include('wars.php');
  8.   else if ($_GET['page']='team')
  9.     include('team.php');
  10.   else
  11.     include('news.php'); // page par défaut si erreur
  12. }else
  13. { include($info);
  14. }


 
 
sera beaucoup plus sécurisé. Ce que t'as fait faire l'autre bonhomme est l'exemple typique de la fameuse faille du moins s'il n'y a rien d'autre pour vérifier la valeur.
 
Il ne faut jamais utiliser directement le contenu d'une valeur venant de l'extérieur sans avoir au choix :

  • vérifier son contenu (comme ici avec les if) et la validité de son contenu (par exemple si on recoit une chaine de caractére alors qu'on s'attend à avoir un nombre ;) )
  • désactiver tout élément dangereux du contenu de la variable (par exemple à l'aide d' "htmlentities()" si on affiche à l'écran le contenu de la variable


De plus, il faut toujours vérifier l'existance des variables venant de l'extérieur ou d'un autre fichier php inclus avant de s'en servir. Sinon, ca affichera une alerte si le serveur est réglé pour.


 
Exactement ce que je cherchais. J'utilise pas le switch car j'apprend doucement. Include est une des premières choses qu'on voit en apprenant le php donc je préfère bien le maitriser avant de voir le switch.
 
Sinon le $info sort du mec qui me l'a filé. Je n'ai jamais créé de valeur $info.

Reply

Marsh Posté le 24-08-2005 à 18:08:09    

J'ai oublié de changer le dernier $info. :lol:
et j'ai aussi un autre petit bug ligne trois. :lol:
Je crois que j'ai voulut aller trop vite.

Reply

Marsh Posté le 24-08-2005 à 18:13:43    

Je met quoi alors ?
Car bon je suis pas encore très très bon.
Ligne 3 je dois enlever un des guillements.
Mais je vois pas quoi mettre a la place du $info :/

Reply

Marsh Posté le 24-08-2005 à 18:13:43   

Reply

Marsh Posté le 24-08-2005 à 18:18:06    

de toute façon, quelles que soient les sécurités, hacker vaillant rien n'est impossible


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 24-08-2005 à 18:32:47    

rask09 > Tu mets le nom de la page à afficher par défaut. Cette ligne là, c'est si $_GET['page'] n'existe pas, donc si on n'a rien indiqué à php.
Les lignes deux et trois, c'est si on t'indique une valeur vide.

Reply

Marsh Posté le 24-08-2005 à 19:07:16    

J'ai mis news.php.
 
Merci beaucoup.

Reply

Marsh Posté le 24-08-2005 à 19:36:18    

Harkonnen a écrit :

de toute façon, quelles que soient les sécurités, hacker vaillant rien n'est impossible


harko, hacker dans l'ombre.

Reply

Marsh Posté le 24-08-2005 à 20:55:35    

masklinn a écrit :

Comment j'vous ai grillés sur le switch [:kbchris]
 
Sauf que je crois me souvenir que le fallthrough est actif dans les switch PHP, donc tout ce que tu vas faire c'est  

Citation :

die ("oula la, mais que se passe t'il !?!?" );


quelle que soit la donnée rentrée

ouais, bon, il manque les "break" correspondant :o  
C'était juste pour laisser quelque chose à faire au lecteur :whistle:  

Reply

Marsh Posté le 24-08-2005 à 22:06:58    

oui oui. sinon y'a bien un effet cascade en php.  :) "fallthrough" comme dirait masklinn.  :sol:

Reply

Marsh Posté le 24-08-2005 à 22:10:57    

Et bien, j'aurais appris un mot aujourd'hui (sous réserve que je m'en souvienne, ce qui n'est pas gagné :pt1cable: )


Message édité par mrbebert le 24-08-2005 à 22:11:35
Reply

Marsh Posté le 24-08-2005 à 22:12:54    

pmusa a écrit :

oui oui. sinon y'a bien un effet cascade en php.  :) "fallthrough" comme dirait masklinn.  :sol:


Cascade ne traduit pas vraiment la notion de fallthrough :o


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 24-08-2005 à 22:15:12    

pourquoi, j'ai l'impression d'avoir été téléporté sur mars depuis tout à l'heure? :o

Reply

Marsh Posté le 24-08-2005 à 22:17:35    

bah c'est comme ça qu'on l'appelle en français ce phénomène. rrahhh genre toi et florentg avec vos mots staÿÿÿle "full bracketed syntaxe" "fallthrough"...  :o  
 
désolé mais ça s'appelle bien "l'effet cascade".  :non: j'entend par là le fait que si php trouve pas de break pour le "case" auquel il répond TRUE bah il va continuer jusqu'à qu'il bute enfin sur un break. donc on se comprend...  [:airforceone]  
 
pour une fois que j'ai raison allez stp masklinn.  :D

Reply

Marsh Posté le 24-08-2005 à 22:19:37    

pmusa a écrit :

bah c'est comme ça qu'on l'appelle en français ce phénomène. rrahhh genre toi et florentg avec vos mots staÿÿÿle "full bracketed syntaxe" "fallthrough".


Pour florentg je sais pas, pour moi c'est la pluspart du temps que je ne connais même pas les équivalent français (si équivalents il y a), et souvent quand on me les donne je les trouve stupides :/


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 24-08-2005 à 22:29:35    

oui je sais bien, mais quand tu sors "fallthrough" dans une conversation ça parle pas pour tous le monde.  :D mais je dois avouer qu'en anglais c'est tellement plus ---> http://www.designlaboratory.net/smileyyyy/bogoss.gif
 
notre masklinn national.  :wahoo:

Reply

Marsh Posté le 24-08-2005 à 22:30:27    

pmusa a écrit :

oui je sais bien, mais quand tu sors "fallthrough" dans une conversation ça parle pas pour tous le monde.  :D mais je dois avouer qu'en anglais c'est tellement plus ---> http://www.designlaboratory.net/smileyyyy/bogoss.gif


C'est pas ma faute si vous êtes tous stupides [:ma muse]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 13-09-2006 à 12:31:35    

J'ai un doute, a t-on un souci de faille include avec ce type de code :

Code :
  1. include $chemin_racine.'includes/header.php';


Ou est-ce uniquement avec l'utilisation de $_GET ?

Reply

Marsh Posté le 13-09-2006 à 12:56:17    

Bin si t'as le register_global à on, y'a un souci potentiel puisque l'utilisateur pourra définir la valeur de $chemin_racine
 
http://us2.php.net/register_globals


---------------
Sonnerie polyphonique - Sonnerie Hi-Fi - Sonnerie Ultrason  
Reply

Marsh Posté le 13-09-2006 à 13:27:47    


 
1°) Tu obscurcis ta variable page en mettant à la place index.php?supermofo=(md5(detapage))
2°) Tu rewrite ca en une url friendly /monsite/mapage.html => RewriteRule ^([a-z0-9]{32})/mapage\.html$ index.php?supermofo=1 [L]
3°) Tu cree un tableau de l'ensemble de tes pages et tu check si la page demandée existe isset($array[get['supermofo']) ?
4°) Tu filtres pour ne recevoir des des md5  : $page = ctype_alnum($GET['supermofo']) ? $GET['supermofo']: "erreur";
5°) normalement t securisé à block
6°) evite les "page" == "truc" ;)
 
Edit si t en register global, le passer à off , sinon définir tes pages comme des constantes avec DEFINE
 
Compliqué ?

Message cité 1 fois
Message édité par supermofo le 13-09-2006 à 20:05:05
Reply

Marsh Posté le 13-09-2006 à 17:34:44    

supermofo a écrit :


5°) normalement t securisé à block


bah non.
Un include, il peut faire un include d'un fichier distant ?  
parce que si c'est le cas, a ta page j'envoie l'adresse http://monsite.com/ma_page_tres_mechante.txt, adresse chiffré en md5 et op, faille de cross scripting.

Citation :


Compliqué ?


oui, un switch suffit et est plus secure  [:dawa]


---------------
my flick r - Just Tab it !
Reply

Marsh Posté le 13-09-2006 à 20:03:26    

zapan666 a écrit :

bah non.
Un include, il peut faire un include d'un fichier distant ?  
parce que si c'est le cas, a ta page j'envoie l'adresse http://monsite.com/ma_page_tres_mechante.txt, adresse chiffré en md5 et op, faille de cross scripting.
 
oui, un switch suffit et est plus secure  [:dawa]


 
Mais non puisqu'il stocke un tablo des pages de son site:
 

Code :
  1. $mes_pages = array("md5(page1)"=> "page1.php", ... , "md5(page2)"=> "page2.php" );
  2. if(!isset($mes_pages[$_GET['XXX'])) die("retour à l'envoyeur" );

Reply

Marsh Posté le 13-09-2006 à 20:31:09    

supermofo a écrit :

Mais non puisqu'il stocke un tablo des pages de son site:
 

Code :
  1. $mes_pages = array("md5(page1)"=> "page1.php", ... , "md5(page2)"=> "page2.php" );
  2. if(!isset($mes_pages[$_GET['XXX'])) die("retour à l'envoyeur" );



 
a ok
mais...ça sert a quoi de mettre le nom de la page en md5 dans la variable ?  [:theepsilon]  
En clair, c'est tout aussi secure non ?  [:dawa]


---------------
my flick r - Just Tab it !
Reply

Marsh Posté le 14-09-2006 à 08:54:56    

Une autre solution que j'utilise avec la technique du "index.php?page=news":
Soit un site qui a une architecture comme ci-dessous :

Code :
  1. index.php
  2. pages/news.php
  3. pages/contact.php


 
Il est possible de faire cela dans l'index.php:

Code :
  1. if(!file_exists(dirname(__FILE__).'/pages/'.$_GET['page'].'.php')){
  2. $page="error.php";
  3. }else{
  4. $page = $_GET['page'];
  5. }
  6. include(dirname(__FILE__).'/pages/'.$page.'.php');


 
Aucune faille de sécurité possible puisque tu vérifie sur le serveur si la page existe avant de l'inclure.


Message édité par NoiBe49 le 14-09-2006 à 08:57:46
Reply

Marsh Posté le 14-09-2006 à 10:42:12    

NoiBe49 > Ce que tu fais est dangereux. Ca permet sur pas mal de site d'acceder aux pages d'administration protégées par htacess en tapant index.php?page=../admin/index
 


---------------
Sonnerie polyphonique - Sonnerie Hi-Fi - Sonnerie Ultrason  
Reply

Marsh Posté le 14-09-2006 à 11:49:36    

Mes sites sont souvent organisés de cette manière :

Code :
  1. <base>/index.php
  2. <base>/cfg/cfg.php
  3. <base>/images/
  4. <base>/admin/index.php
  5. <base>/admin/pages


 
Comme tu peux le voir dans mon code, mon script vérifie si la page demandée existe dans "<base>/pages/" donc impossible de réussir à inclure un fichier présent dans "<base>/admin/pages/"
 
Ca aurait pu être dangereux si mon script était :

Code :
  1. if(!file_exists($_GET['page']){


 
or là il est
 

Code :
  1. if(!file_exists(dirname(__FILE__).'/pages/'.$_GET['page'].'.php')){


 
A moins que je me gourre quelque part et là, je suis tout ouïe.


Message édité par NoiBe49 le 14-09-2006 à 11:52:56
Reply

Marsh Posté le 14-09-2006 à 11:51:07    

tu as le droit de mettre un ../admin dans le chemin :o


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 14-09-2006 à 12:00:01    

Le moyen que j'ai trouvé moi, avec une structure où les différentes pages du site correspondent à des fichiers dans un répertoire particulier (comme pour NoiBe49):
 
1- Je nettoie ma variable $page. Je m'attends à ce qu'elle contienne des lettres, des chiffres, des tirets ou des underscore. Tout autre caractère est supprimé.
2- Je vérifie l'existence du fichier php en question. La variable ayant été nettoyée, j'ai l'assurance que c'est bien dans le bon répertoire que je vérifie.
3- Si le fichier existe, affichage, sinon redirection vers une page par défaut.
 
C'est blindé, pas besoin d'obfuscation, pas besoin de switch. Une simple restriction sur les valeurs autorisée ou pas pour la variable convient.


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 14-09-2006 à 12:11:38    

En effet, j'avais oublié de préciser que je supprimer les caractères "sensibles". Tout comme Kriscool, un contrôle des caractères de la variable est plus que recommandé avant d'effectuer le test d'existence du fichier.

Reply

Marsh Posté le 14-09-2006 à 12:15:37    

NoiBe49 a écrit :

Tout comme Kriscool, un contrôle des caractères de la variable est plus que recommandé avant d'effectuer le test d'existence du fichier.


 
Même au delà de ça, je pense que c'est suffisant.
Une autre parade simplissîme pour certaines variables, c'est de tronquer leur taille. Beaucoup de failles passent par la transmission d'un code php ou js encodé dans une variable. Une fois ce code tronqué, il marche moins bien [:petrus75]. Bon ceci dit, ça ne remplace pas un petit nettoyage en règle au niveau caractères.


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 14-09-2006 à 12:58:54    

zapan666 a écrit :

a ok
mais...ça sert a quoi de mettre le nom de la page en md5 dans la variable ?  [:theepsilon]  
En clair, c'est tout aussi secure non ?  [:dawa]


 
Le md5 est là pour dissimuler la page dans l'url donc la faille potentielles. Tu px utiliser autre chose que le md5 par exemple sous-domaine,indice-de-repertoire,indice-de-page pour indentifier ta page. Ex: http://sd.monsite.com/5,24,56/  En fait n'importe quel serie de chiffre suffisamment non explicite .
 

Code :
  1. foreach (glob("*.php" ) as $v){
  2. $file_cache[sha1($v . time())] = $v;
  3. }
  4. $handle = fopen("./file_cache.inc.php","w" );
  5. fwrite($handle, "<?php \$file_cache=" . var_export($file_cache, 1) . ";?>" );
  6. fclose($handle);
  7. /* Auteur Ilia http://ilia.ws */
  8. //dans les autres pages
  9. define('document_root','/usr/local/www/inc_dir/')
  10. include(document_root . file_cache.inc.php);
  11. if(!isset($file_cache[$_GET['monparam'])) die("Go away hacker" );


 
Enlever les Header X-Powered by : PHP (4|5).xx serait également une idée pour ceux qui joue avec les injecteurs de requetes sous FF.

Message cité 3 fois
Message édité par supermofo le 14-09-2006 à 17:31:26
Reply

Marsh Posté le 14-09-2006 à 13:21:44    

supermofo a écrit :

Le md5 est là pour dissimuler la page dans l'url donc la faille potentielles.


 
Explique moi l'intérêt de faire ça, quand tu as nettoyé la variable passée en paramètre ? [:jean-guitou]
Qu'un attaquant potentiel sache que http://mon.site.fr/index.php?page=toto fait un include sur http://mon.site.fr/pages/toto.php ne lui servira strictement à rien si on ne lui laisse aucun moyen de détourner ce mécanisme.


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 14-09-2006 à 14:08:51    

supermofo a écrit :

Le md5 est là pour dissimuler la page dans l'url donc la faille potentielles. Tu px utiliser autre chose que le md5 par exemple sous-domaine,indice-de-repertoire,indice-de-page pour indentifier ta page. Ex: http://sd.monsite.com/5,24,56/  En fait n'importe quel serie de chiffre suffisamment non explicite .


 
C'est bien aussi les urls explicites, c'est pratique...
 
Même réaction que kriscool concernant l'intérêt du md5...
 
 

Reply

Marsh Posté le 14-09-2006 à 17:09:33    


olol comme tu te prends la tête pour rien  [:bap2703]  
Ton histoire de md5, non seulement c'est inutile, mais en plus ça va nuire au référencement de tes pages. Bah oui, je te rappelle que les adresses de tes pages, c'est plus mieux si elles sont explicites, et en rapport avec la page.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed