2011-07-16 6 views
2

Je crée une visionneuse source PHP de base pour le dossier de code exemple de mon blog.Comment utiliser file_get_contents en toute sécurité?

<?php 

if (isset($_GET['file'])) 
{ 
    header('Content-type: text/plain'); 
    $filename = realpath($_GET['file']); 
    if (startsWith($filename, dirname(__FILE__))) 
    { 
     echo file_get_contents($filename); 
    } 
} 

function startsWith($haystack, $needle) 
{ 
    $length = strlen($needle); 
    return (substr($haystack, 0, $length) === $needle); 
} 

?> 

Est-ce que j'ai ici suffisamment qu'il ne permettra jamais un fichier en dehors du répertoire dans lequel ce script est situé, ou sous-répertoires du répertoire de ce script, être vu? Je suppose qu'il y a une meilleure solution que startsWith aussi, pour vérifier si un chemin est un descendant d'un répertoire particulier?

Répondre

3

Ça va être sûr, oui. La partie realpath est ce que vous avez à faire, et vous le faites. Ce code fait ce qu'il est censé faire.

+0

Mais 'realpath()' seule n'empêche pas de se lection d'un autre répertoire, il a donc toujours besoin de sa fonction 'startsWith()' pour vérifier si le fichier demandé se trouve dans le répertoire autorisé. Mais dans l'ensemble, la solution semble sauver. – feeela

+0

@feeela: 'realpath' ne fait évidemment rien de ce genre - cela ne fait pas partie de la description de la fonction. Ce que je veux dire, c'est que le test 'startsWith' est quelque chose que tout le monde penserait faire, mais ce n'est pas sûr * par lui-même *. C'est la combinaison avec 'realpath' qui le rend sûr. – Jon

0

Vous pouvez réduire l'entrée d'un nom de fichier (voir finfo) et spécifier le répertoire dans lequel effectuer la recherche, s'il s'agit du même répertoire à chaque fois. Vous n'avez donc pas besoin de vérifier via startsWith().

Si vous voulez seulement afficher le code source PHP, essayez d'activer * .phps-file-handling dans votre serveur web. Voir: https://serverfault.com/questions/62410/apache-htaccess-phps

+0

Eh bien, je ne peux pas réduire l'entrée à juste un nom de fichier, puisque je veux aussi permettre l'affichage des fichiers dans les sous-répertoires du répertoire de base. En ce qui concerne la deuxième partie, je cours IIS. ;) –

+0

@Jake Petroules "Je cours IIS" [C'est une mauvaise excuse] (http://learn.iis.net/page.aspx/753/enable-php-syntax-highlighting-on-iis-7/ :) :) – feeela

0

En aparté, regardez en utilisant strncmp au lieu de votre fonction startsWith personnalisée.

0

Si je devais aborder un projet comme cela, je:

Utilisez une combinaison de votre solution & htaccess pour masquer le nom du fichier d'origine comme ayant:

http://example.com/viewsource ?. .php file =/projet1/index.php

serait trop évident et tentant de mess avec, en utilisant htaccess vous pourriez avoir:

http://example.com/source/project1/index.php

qui pointe aussi

h1ddEnfIlEs/Viewsource/index.php? File = 1 & dossier = 2

$
RewriteRule ^source/([a-z0-9]+)/([a-z0-9]+).php$ h1ddEnfIlEs/viewSourceScript/index.php?file=$2&project=$1 
$

ensuite avec le spectateur source h1ddEnfIlEs/viewSourceScript/index.php

<?php 
if(
is_dir('./h1ddEnfIlEs/'.$_GET['project'].'/')===true && 
is_file('./h1ddEnfIlEs/'.$_GET['project'].'/'.basename($_GET['file'])) 
){ 
    highlight_file('./h1ddEnfIlEs/'.$_GET['project'].'/'.basename($_GET['file'])); 
} 
?> 
Questions connexes