据我所知,PHP将文件保存到临时目录,之后我可以通过$ _FILES处理该文件。
我需要在PHP开始下载文件之前检查一些东西 - 如果会话有效,如果referrer有效...那么我可以防止未经授权的上传者将垃圾保存到php临时目录。
这是怎么做的?
我知道如何在perl中做得很好,但我正在寻找没有php.ini修改或.htaccess修改的纯PHP解决方案。
答案 0 :(得分:2)
当您将Content-Type更改为PHP无法解析的内容时(例如'raw / data'),您可以从php://input
读取所有POST数据,因此当脚本运行时您可以执行首先验证,如果您满意,则读取数据并将其保存到磁盘。
这是PHP代码
<?php
preg_match("/^(.*)\/([^\/]+)$/", $_SERVER['SCRIPT_NAME'], $SRVR);
$SRVR=$_SERVER['HTTP_ORIGIN'].$SRVR[1];
if (!strstr($_SERVER['HTTP_REFERER'], $SRVR)) {
echo "Status: 418 I'm a teapot (RFC 2324)\n\n";
exit;
}
session_name('MYSESSION');
session_start();
if (!$_SESSION['LoggedID']) {
echo "Invalid Session";
exit;
}
session_write_close(); // quite useful - 'unlock' the session variables
$HEADERS=getallheaders();
if (!$HEADERS['UPL_FileName']) {
echo "Invalid FileName";
exit;
}
if (!$HEADERS['UPL_TMP']) {
$HEADERS['UPL_TMP']=rtrim(base64_encode(md5(microtime())),"=");
}
$in=fopen('php://input', 'r');
$SIZE=0;
$out=fopen('tmp/'.$HEADERS['UPL_TMP'], 'wb');
while(!feof($in)){
usleep(10000); // simulate slow upload - for testing progress status/bar
fwrite($out, fgets($in, 2048));
}
fclose($out);
fclose($in);
rename('tmp/'.$HEADERS['UPL_TMP'], $HEADERS['UPL_FileName']);
echo "Upload OK [", $HEADERS['UPL_TMP'], "]";
?>
以及JavaScript代码
function getXMLHttp() {
var ajax;
if (window.XMLHttpRequest) {
ajax=new XMLHttpRequest();
} else {
ajax=new ActiveXObject('Microsoft.XMLHTTP');
}
return ajax;
}
var ajax=getXMLHttp();
ajax.onreadystatechange = function () {
if (this.readyState==4) {
console.log(this.responseText);
}
}
ajax.open('POST', 'upload.php', true);
ajax.setRequestHeader('Content-Type', 'raw/data');
ajax.setRequestHeader('UPL_FileName', 'tmp/test.jpg');
ajax.setRequestHeader('UPL_TMP', 'ABCDE');
ajax.send(document.getElementById('uploader').files[0]);
...期待文件标签的id ='uploader'
希望它会帮助某人; - )
答案 1 :(得分:0)
简答:以正常形式发布操作,没有。 PHP不能“要求更多”。通过PUT或POST作为multipart/form-data
通过表单上传的文件离开客户端,进入您的Web服务器,并完全交给PHP处理到$_FILES
。
显然,在a host of other vulnerabilities中,拒绝服务攻击已经成熟。
Javascript,特别是使用the HTML5 File API,您可以在浏览器中访问文件数据。然后,您可以将所述文件数据的任何部分发送回PHP进行验证(使用XHR),然后在验证通过后继续上传。