下载脚本返回损坏的下载文件


Download script returns corrupted download files

我创建了一个下载脚本,目的是隐藏文件位置,并迫使经过我们网站的人下载文件。它应该返回一个.jar文件。当我发布一个.jar文件下载时,它会返回corrupt!因此,我们将文件扩展名更改为.zip,以测试这是否可行。现在我可以自己下载,但其他人仍然报告文件损坏。。。

以下是实时下载页面的链接:https://www.run2stay.com/?p=download

这是下载中使用的代码。hp:

<? session_start(); 
include_once("inc/conf.php");
if ($stmt = $slc->prepare("SELECT   id,
                                creator,
                                name,
                                version,
                                discription,
                                changelog,
                                readme,
                                file,
                                datum,
                                downloads
                        FROM download ORDER by id desc")) {
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 0) {
    echo "<h3>Oops!</h3><p>Seems like there are no downloads yet!</p>";
} else {
    $stmt->bind_result($down_id, $creat, $name, $vers, $disc, $change, $read, $file, $dat, $down);
    while ($stmt->fetch()) { ?>
<h3 id="<?=$down_id;?>"><?=$name;?> <?=$vers;?> <i>by <?=$creat;?></i></h3>
<?=$dat;?>
<? if (!empty($disc)) { ?>
<h4>Discription:</h4>
<p id="ber"><?=$disc;?></p>
<? } if (!empty($change)) { ?>
<h4>Changelog:</h4>
<p id="ber"><?=$change;?></p>
<? } if (!empty($read)) { ?>
<h4>Readme:</h4>
<p id="ber"><?=$read;?></p>
<? } ?>
<h4>Download:</h4>
<? $_SESSION["dl"] = $_SERVER["HTTP_HOST"]; ?>
<input type="button" value="download" onclick="location.href='?p=dl&get=<?=$file;?>&w=<?=$down_id;?>';">&nbsp;<?=$down;?> times downloaded.
<hr>
<? } } } ?>

我在dl.php 中使用的代码

<?php
include_once("inc/conf.php");
if (!empty($_GET)) {
$file = htmlspecialchars($_GET['get']);
$file = "mods/$file";
$down_id = htmlspecialchars($_GET['w']);
session_start();
if(isset($_SESSION["dl"])) {
$referrer = $_SERVER["HTTP_REFERER"];
$referrer = parse_url($referrer);
if($referrer["host"] != $_SESSION["dl"]) {
echo "<meta http-equiv=refresh content=0;URL=?p=download>";
die();
  }
} else {
echo "<meta http-equiv=refresh content=0;URL=?p=download>";
die();
}
unset($_SESSION["dl"]);
if (file_exists($file)) {
header('Content-Description: File Transfer'); 
header("Expires: fri, 1 Jan 2016 00:00:00 GMT"); // Don't change.
header('Content-Type: application/java-archive');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile("$file");
$qry = "UPDATE download SET downloads=downloads+1 WHERE id=?";
$stmt = $slc->prepare($qry);
$stmt->bind_param('s',$down_id);
$stmt->execute();
$stmt->close();
exit;
} else {
echo "<h3>Oops!</h3><p>Looks like something horrible went wrong!</p>";
}
}
?>

下载文档并用文本编辑器(如NotePad++)打开它,看起来就像是先输出一个完整的HTML文档标题(直到您的网站的导航菜单和section元素),然后才有二进制数据,看起来可能是压缩数据。

我假设您的结构是以一种基于查询字符串参数动态包含内容的方式设置的,例如?p=download用于下载页面,?p=dl&get=r2s-Radio-1.7.10-1.0.0.ALPHA.zip&w=1用于下载二进制文件内容本身。

您的错误似乎是,在评估p参数包含的内容之前,在任何情况下都包含页面的HTML标头

你需要用另一种方式:如果请求zip文件内容,则输出该内容,并且在它之前(或之后)不输出HTML代码——并且只有当请求不应该是文件下载时才输出HTML代码。


编辑:顺便说一句,这是一个危险的设置。p参数似乎允许在服务器上包含几乎任何以.php结尾的文件,例如https://www.run2stay.com/?p=index,这将使索引页一次又一次地将自己包含在内。如果其他脚本文件也可能存在这种情况,其中包含密码等潜在的敏感内容,甚至可能包括路径遍历(未检查),那么您在这里遇到了严重问题。