2014-01-05 92 views
0

我有这样的PHP代码:如何在本PHP代码中防止本地文件下载?

<?php 

header("Content-Type: application/force-download"); 
header("Content-Disposition: attachment; filename=\"".$_GET['name']."\""); 
$file_content = file_get_contents($_GET['name']); 
echo $file_content; 

?> 

在这种情况下,攻击者可以申请在我的网站上下载文件:

localhost/file.php?name=../../../../../../../etc/passwd

我需要一种方法来防止用户下载任何东西从当前目录中除去.zip文件。

+0

如果(!strpos($ _ GET [ '名'], '..')==假)退出; –

+1

@IgorPantović这是不够的,只是开始使用绝对路径名称 –

+0

@MichaelHelwig噢,我的确,可怕的疏忽。 –

回答

1

在打开文件之前,您应该检查$_GET['name']的内容是否合法。

特别是,在你的情况,请检查:

  • .zip
  • 它不包含一个NULL字节,以防止过早终止字符串结尾(见Null bytes related issues
  • 它不包含路径分隔符(/\)。

下面是一个例子:

$filename = $_GET['name']; 
if (strpos($filename, "\0") !== false) { 
    // contains NUL byte 
} else if (substr(strtolower($filename), -4) !== '.zip') { 
    // doesn’t end with ".zip" 
} else if (basename($filename) !== $filename) { 
    // contains path separator 
} else if (!is_file($filename)) { 
    // file does not exist 
} else { 
    // everything is fine 
} 
+0

这还不够。只要想一想'/ etc/passwd%00.zip'(以'.zip'结尾,但包含字符串终止NUL字节)或'./../../ etc/passwd'(不以'..'开头)。 – Gumbo

+0

的确,我错过了一些案例。我相应地调整了我的答案。 (但是,我没有提到NUL字节技巧,因为我不确定我完全理解它) – gturri

+0

它仍然不够/不够准确。 – Gumbo

相关问题