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.

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

报告相同问题?

悬赏问题

  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路