dongweng6241 2016-01-10 14:09
浏览 31
已采纳

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

I have created a download script in order to hide the file location and to force people passing by our website to download a file. it should return a .jar file. When i post a .jar file to download it'll return corrupt! so we changed the file-extension to .zip to test if that would work. Now i can download it for myself but other people still report corruption of the file...

here's a link to the live download page: https://www.run2stay.com/?p=download

here's the code used inside download.php:

<? 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>

<? } } } ?>

The code i used inside 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>";
}
}
?>
  • 写回答

1条回答 默认 最新

  • dongxindu8753 2016-01-10 14:32
    关注

    Downloading the document and opening it with a text editor such as NotePad++, it looks like you are outputting a whole HTML document header first (up until your site’s nav menu and a section element) – and only then there’s binary data that looks like it might be zip-ped data.

    I presume that your structure is set up in a way where you dynamically include content based on the query string parameter, such as ?p=download for the download page, and ?p=dl&get=r2s-Radio-1.7.10-1.0.0.ALPHA.zip&w=1 for the download of the binary file content itself.

    Your mistake seems to be, that you are including the HTML header for the page in any case, before evaluating what the p parameter contains.

    You need to do it the other way around: If the zip file content is requested, output that, and no HTML code before (or after) it – and output HTML code only when the request is not supposed to be a file download.


    Edit: And btw., that’s a dangerous setup you have there. The p parameter seems to allow to include just about any file with the ending .php on your server – such as https://www.run2stay.com/?p=index, which will make the index page include itself into itself over and over again. If that is possible for other script files, with potentially sensitive content such as passwords, as well, maybe even including path traversal (didn’t check), then you have a serious problem here.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大