When uploading big file (>100M) to server, PHP always accept entire data POST from browser first. We cannot inject into the process of uploading.
For example, check the value of "token
" before entire data send to server is IMPOSSIBLE in my PHP code:
<form enctype="multipart/form-data" action="upload.php?token=XXXXXX" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="3000000" />
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
So I've try to use mod_rewrite
like this:
RewriteEngine On
RewriteMap mymap prg:/tmp/map.php
RewriteCond %{QUERY_STRING} ^token=(.*)$ [NC]
RewriteRule ^/upload/fake.php$ ${mymap:%1} [L]
map.php
#!/usr/bin/php
<?php
define("REAL_TARGET", "/upload/real.php\n");
define("FORBIDDEN", "/upload/forbidden.html\n");
$handle = fopen ("php://stdin","r");
while($token = trim(fgets($handle))) {
file_put_contents("/tmp/map.log", $token."\n", FILE_APPEND);
if (check_token($token)) {
echo REAL_TARGET;
} else {
echo FORBIDDEN;
}
}
function check_token ($token) {//do your own security check
return substr($token,0,4) === 'alix';
}
But ... It fails again. mod_rewrite
looks working too late in this situation. Data still transfer entirely.
Then I tried Node.js
, like this (code snip):
var stream = new multipart.Stream(req);
stream.addListener('part', function(part) {
sys.print(req.uri.params.token+"\n");
if (req.uri.params.token != "xxxx") {//check token
res.sendHeader(200, {'Content-Type': 'text/plain'});
res.sendBody('Incorrect token!');
res.finish();
sys.puts("\n=> Block");
return false;
}
Result is ... fail again.
So please help me to find the correct path to resolve this issue or tell me there is no way.
Related questions:
Can PHP (with Apache or Nginx) check HTTP header before POST request finished?
It sounds like you're trying to stream the upload and need to validate before processing: Does this help? http://debuggable.com/posts/streaming-file-uploads-with-node-js:4ac094b2-b6c8-4a7f-bd07-28accbdd56cb
http://www.componentix.com/blog/13/file-uploads-using-nodejs-once-again