0

私は基本的なライセンス検証済みのPHPダウンロードスクリプトを書いています。ターゲットファイルは約50MBで、一部のファイルで機能します。他の人はそれを終えることができず、時々それを再試行することはうまくいきます。

スクリプトは次のとおりです。

$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に感謝します。

4

1 に答える 1

0

readfile()ファイル全体を一度にバッファに入れる関数です。おそらくPHPがタイムアウトするのを防ぐでしょう。下部にあるループの代わりに使用してくださいfopen()print()

別の解決策は、サーバーがmod_x_sendfilePHPからapache内部へのダウンロードを取得するために持っているかどうかを確認することです。

編集:sendfileを試したとおっしゃっています。あなたがそれを機能させることができれば、より良いオプションかもしれません。

于 2012-11-09T04:05:07.097 に答える