2011-07-16 52 views
2

我正在为我的博客的示例代码文件夹制作基本的PHP源代码查看器。如何安全地使用file_get_contents?

<?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); 
} 

?> 

是我在这里充分的,它绝不允许在此脚本所在的目录,或该脚本的目录的子目录之外的文件,来看待?我猜测有比startWith更好的解决方案,用于检查路径是否是特定目录的后代?

回答

3

这将是安全的,是的。 realpath部分是你必须做的,你正在做。这段代码做了它应该很好的事情。

+0

但是'真实路径()'本身并不从本质上阻止因为他需要他的'startsWith()'函数来检查请求的文件是否在允许的目录中。但总而言之,解决方案似乎可以挽救。 – feeela

+0

@feeela:'realpath'显然不会做这样的事 - 它不是函数描述的一部分。我想说的是'startsWith'检查是每个人都会想到的事情,但它本身并不安全*。它与'realpath'的组合使得它更安全。 – Jon

0

您可能会减少输入到文件名(请参阅finfo)并指定要搜索的目录(如果每次都是相同的目录) - 因此您无需通过startsWith()进行检查。

如果您只想显示PHP源代码,请尝试在您的Web服务器中启用* .phps-file-handling。请参阅:https://serverfault.com/questions/62410/apache-htaccess-phps

+0

嗯,我不能减少输入只是一个文件名,因为我想启用查看基目录的子目录内的文件。至于第二部分,我正在运行IIS。 ;) –

+0

@Jake Petroules“我正在运行IIS”[这是一个糟糕的借口](http://learn.iis.net/page.aspx/753/enable-php-syntax-highlighting-on-iis-7/ ):) – feeela

0

另外,请使用strncmp来代替您的自定义startsWith函数。

0

如果我是接近一个项目这样我会:

使用您的解决方案的组合& htaccess的掩盖原始文件名具有:

http://example.com/viewsource ?PHP文件=/PROJECT1/index.php文件

会太明显,诱人的更动,使用htaccess你可以有:

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

指向太

h1ddEnfIlEs/viewSource /的index.php?文件= $ 1 &文件夹= $ 16

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

然后用源代码查看器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'])); 
} 
?> 
相关问题