Reputation: 21
new guy here asking a question that what should be met with simple solutions.
I have tried a bunch of code. It seems I can get the file stream for getimagesize and get other things to work without crashing.
I'm dusting off an old project that needs to limit the files uploaded so that they are only image files and nothing evil.
This code always give me an error message no matter what
$imageinfo = getimagesize($_FILES['bf_file'][$key]['tmp_name']);
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') {
alert ("Sorry, we only accept GIF and JPEG images");
exit;
}
Here is the black list effort
$blacklist = array(".php", ".phtml", ".php3", ".php4", ".js", ".shtml", ".pl" ,".py"
,".txt", ".doc");
foreach ($blacklist as $file)
{
if(preg_match("/$file\$/i", $_FILES['bf_file'][$key]['tmp_name']))
{
alert "ERROR: Uploading executable files Not Allowed\n";
exit();
}
}
Here is another getimagesize
$size = getimagesize($_FILES[bf_file][$key][tmp_name]);
$fp = fopen($_FILES[bf_file][$key][tmp_name], "rb");
if ($size && $fp) {
header("Content-type: {$size['mime']}");
fpassthru($fp);
continue;
} else
// error
alert("Inappropriate file type");
On each of these I get the error message no matter if a file is uploaded or not.
I just need to place these controls somewhere in my file so that if the uploaded file passes the checks then everything just passes through as the uploader and everything else works like it should but without the benefit of these limiters and checks.
Also, the user should not be required to upload file. There are 3 fields, subject, body and file upload. Only subject and body are required to have data and that works right now.
Any help will be greatly appreciated.
Thanks,
James
Upvotes: 2
Views: 2941
Reputation: 2434
By far the safest approach is to prevent your webserver from executing dynamic stuff in folders that user can upload to entirely. Then it doesn't matter what they upload.
An .htaccess file in your uploads directory containing php_flag engine off
will prevent php. Other executable stuff should be disabled by default anyway, but you should definitely check.
Upvotes: 0
Reputation: 95121
Your script is all over the place example
$imageinfo = getimagesize($_FILES['bf_file'][$key]['tmp_name']);
To get temp name should be $_FILES['bf_file']['tmp_name'][$key]
and also file size is already returned via $_FILES['bf_file']['size'][$key]
Why don't you take a look at for details example on similar question
multi image upload wrong quantity on file-upload
Uploading images with the help of arrays and fetch errors
Upvotes: 1
Reputation: 11869
In first snippet. Well, getimagesize()
actually returns MIME type (contrary to what Baba says), but you shouldn't depend on it. It's entirely possible to make file which at beginning looks like PNG GIF (any reason to block PNG?), but after header has <?php dangerous_code(); ?>
. Also, I don't know what are you trying with [$key]
. I don't know what it does and array looks like $_FILES[$form_name][$file_field]
(for example $_FILES['file_input']['tmp_size']
. There is no third field. Unless you are doing multiple files uploads, then look into what Baba said (it's very hacky feature). Next, PHP doesn't have alert()
- you probably meant echo
.
In second snippet, I see you're doing stuff incorrectly. Dot is meta character in regular expressions, but in this case it doesn't really matter. Blacklist approaches are flawed anyways as you don't know if your server doesn't support .php5
extension for example. And even if it doesn't, somebody can abuse content negotiation in Apache by making file hack.php.fr
(Apache thinks that .fr
is language). Your approach is flawed - just give PNG files .png
extension no matter what original extension was and so on.
In third example, you activate wrong variable - but also use barewords (you shouldn't, while I'm aware that you should have constants uppercase (so contrary to what PHP says, barewords aren't so dangerous if you have common sense), they are extremally slow, way slower than normal string and make a lot of errors if you have E_NOTICE
(hint: you should)). Next, continue
is not for if
conditionals - it's for loop conditionals (it also works on switch
(as break
), but I guess it's just for consistency).
As for not having to upload files, it's easy. Just do conditional over isset($_FILES['file_input_name'])
.
tl;dr - Learn PHP properly
Upvotes: 1