使用原始$_GET获取文件可能不安全


Can using a raw $_GET to fetch a file be insecure?

作为一名网站管理员,我需要识别有风险的脚本。

我总是编写过滤用户输入的php代码。我从不信任用户输入,选择哪些字符是有效的(与不允许某些字符相比),使用php原生过滤函数(filter_input)或使用lib/frameworks实用程序。

今天,我在下载的模块中搜索安全缺陷,发现了以下代码:

if (isset($_GET['css_file_name'])) {        
    $cssFileName = _PS_MODULE_DIR_ . DS . "xxxx" . DS . "css" . DS . $_GET['css_file_name'] . ".css";
    echo file_get_contents($cssFileName);
 }
 echo "";

我认为这是不安全的,它不尊重基本规则永远不要相信用户的输入。因此,我决定证明这一点,我尝试添加DEL-ascii字符来删除.css,并能够找到任何文件(例如,带有凭据的php文件),但我没有成功。

所以我的问题是:这个代码真的那么不安全吗?有可能用它获取一个php文件吗(你能演示一下吗?)

可能的攻击:函数file_get_contents的空字节中毒可以揭示或包含不正确文件的内容:

$ ls
file.php  nullbyte.php
$ cat file.php 
I am the contents.
$ cat nullbyte.php 
<?php
$input = "file.php'0.jpg";
echo file_get_contents($input);
echo "'n";
?>
$ php nullbyte.php 
I am the contents.

此信息仅与旧版本(不支持)的PHP相关。

PHP 5.3.4中已经修复了空字节中毒(它本身已经是一个旧的、不受支持的PHP版本):https://bugs.php.net/bug.php?id=39863.

可能修复旧版PHP:

<?php
    $clean = str_replace(chr(0), '', $input);
?>

然而,攻击者能够在您的示例中列出整个文件系统的所有可能的CSS文件,有可能突破web根。