2012-11-09 88 views
0

我在写一个基本的许可证验证的PHP下载脚本。目标文件大约50MB,适用于某些文件。其他人无法完成它,有时会重试它。PHP文件下载站点

下面是脚本:

$method = $_GET['method']; 
    if($method == "webdownload") { 
     $airlineid = $_GET['airline']; 

     $sql = "SELECT * FROM airlines WHERE airlineid='$airlineid'"; 
     $result = mysql_query($sql) or die(mysql_error()); 
     $row = mysql_fetch_array($result); 
     if($row['licensekey'] == "") 
      die("Invalid airline id"); 

     $filename = $row['code'].'_installer.exe'; 
     $file_path = '../resources/application/files/'.$row['airlineid'].'/'.$row['clientversion'].'/application_installer.exe'; 
     if($row['licensestate'] != "OK") 
      die("The license associated with this downloaded has been deauthorized."); 

     if(!is_file($file_path)) 
      die("The file associated with this version for this airline appears to be invalid."); 
     //download code here - it runs once only, if refreshed it will not allow it.     

     header('Content-type: application/exe'); 
     header("Content-Disposition: attachment; filename=".$filename); 
     header("Content-Length: ".filesize($file_path)); 
     header("Content-Transfer-Encoding: binary");  

     header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
     header('Pragma: public'); 

     //header('X-Sendfile: '.$file_path); I tried this - it had no effect and I want the portability. 

     $file = @fopen($file_path,"rb"); 
     while(!feof($file)) {   
      $buffer = fread($file, 1024 * 8); 
      print($buffer); 
      flush();    
     } 
     close($file);  
    } 

编辑:经咨询,我发现剧本,等等,是很容易受到SQL注入。我用这个函数替换了直接变量SQL表达式:

 function secure_string($raw) { 
    $sid = strtolower($raw); 
    $sid = str_replace("'","_SINGLE_QUOTE", $sid); 
    $sid = str_replace('"','_DOUBLE_QUOTE', $sid); 


    $cmd[0] = "insert"; 
    $cmd[1] = "select"; 
    $cmd[2] = "union"; 
    $cmd[3] = "delete"; 
    $cmd[4] = "modify"; 
    $cmd[5] = "replace"; 
    $cmd[6] = "update"; 
    $cmd[7] = "create"; 
    $cmd[8] = "alter"; 


    for($index = 0; $index <= 8; $index++) { 
     $sid = str_replace($cmd[$index],"_SQL_COMMAND", $sid); 
    } 

    return $sid;   
} 

这足以阻止SQL注入吗?

EDIT2:我已经使用这个函数与PDO准备函数一起消除这个漏洞。感谢100x让我学到这一课而不会造成灾难性的结果。

+2

快速问题,当我输入''或1 = 1'作为航空公司查询字符串参数时会发生什么? – acqu13sce

+0

立即,没有。但是,我查了一下,当使用'或'1'='1(因为它写在那里)作为参数时,它下载了列表中的第一个文件。我有一个小心脏病发作。我想我明天会花费我的SQL注入漏洞。好,赶快,谢谢。 –

+0

从我的示例sql注入结束时,我错过了'--',当时我注意到我无法编辑我的评论。我建议你看看PDO和参数化查询,以此作为防止此类攻击的简单方法 – acqu13sce

回答

0

readfile()是一个将整个文件一次放入缓冲区的函数。可能会阻止PHP超时。用它代替底部的fopen()print()循环。

另一种解决方案是看看你的服务器是否有mod_x_sendfile,因为这需要从PHP下载并进入apache内部。

编辑:我注意到你说你已经尝试过sendfile。如果你能得到它的工作可能是一个更好的选择。