OK, did a search, couldn't find anything close to this, so here goes...
I'm writing a PHP 5.3+ proxy script to serve files from a directory and subdirectories outside www, htdocs, public_html, etc., eg /home/sites/example.com/data
It's for a Moodle plugin module so if you're familiar with Moodle code, great, if not, I've annotated it as best I can. So far it all works as expected but I've yet to run more tests on it.
The question: How secure is this? My main concern is users gaining access outside the specified directory. If there's anything you can see that is a glaring security flaw, please let me know.
The script:
require_once('../../config.php'); // conatains $CFG object
require_once('../../lib/filelib.php'); // contains mimeinfo() and send_file() definitions
// Don't use Moodle required_param() to avoid sending any HTML messages to Flash apps
require_login(); // Users must be logged in to access files
global $CFG;
$swf_relative_path = get_file_argument(); // gets the appended URL e.g. /dir/subdir/file.jpg
$swf_ok = false;
if(strrpos($swf_relative_path,'.') > strlen($swf_relative_path) - 6) {
// Strip out special characters, extra slashes, and parent directory stuff
$swf_disallowed = array('../','\'','\"',':','{','}','*','&','=','!','?','\\','//','///');
$swf_replace = array('','','','','','','','','','','','','/','/');
$swf_relative_path = str_replace($swf_disallowed,$swf_replace,$swf_relative_path);
$swf_full_path = $CFG->dataroot.$CFG->swf_content_dir.$swf_relative_path;
if(file_exists($swf_full_path) && is_readable($swf_full_path)) {
$swf_path_info = pathinfo($swf_full_path);
$swf_mime_type = mimeinfo('type', $swf_path_info['basename']);
send_file($swf_full_path,$swf_path_info['basename'],'default',0,false,false,$swf_mime_type,false);
exit;
}
}
header('HTTP/1.0 404 Not Found'); // Send back a 404 so that apps don't wait for a timeout
exit('404 Error: File not found'); // Pure text output - Flash app friendly
Thanks in advance! :)
This is super insecure , please do not publish this script on any server.
Do not tinker with ../
and ./
or the other patterns you seem to dislike in your script. Also, just replacing them won't prevent an attacker from inserting the replaced patterns to your script.
For example, have a look at this url:
download.php?file=..././some/file
After replacing ../
with an empty string (like you did), the path of the file is ../some/file
and your script is already broken as it will make files outside of your download root accessible.
One solution to avoid this is using realpath()
. However, I would strongly recommend using an existing and secure script for this purpose.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.