I am trying to create an HTML and PHP script to upload images to a webserver from a user's phone. It is working good in that it will prompt the user to either select an image from their gallery, or to capture an image with their camera. When I capture a picture, it successfully fills in the information
"foo.jpg"
but when I pass the data onto my PHP script, it gives me the error
"Warning getimagesize() filename cannot be empty.... Sorry, there was
an error uploading your file."
What confuses me, is that the filename was not empty in my form. Also, when I submit the form using a desktop computer (it just prompts for a file upload), it works perfectly as it should.
HTML:
<!DOCTYPE html>
<html>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" capture="camera" accept="image/*" name="imageFileToUpload">
<label for="rma">RMA: </label>
<input type="text" name="rma">
<input type="submit" value="Upload Image" name="submit">
</form>
</body>
</html>
PHP:
<?php
$rma = $_POST['rma'];
echo "RMA: " . $rma. "<br>";
$target_dir = "uploads/". $rma;
if (file_exists($target_dir)==false)
{
if(mkdir ($target_dir))
{
echo "folder created at: " .$target_dir . "<br>";
}
else
{
echo "failed to create folder " . $target_dir. "<br>";
}
}
$target_file = $target_dir ."/" .basename($_FILES["imageFileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
// Check if image file is a actual image or fake image
if(isset($_POST["submit"]))
{
$check = getimagesize($_FILES["imageFileToUpload"]["tmp_name"]);
if($check !== false)
{
//echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
}
else
{
echo "File is not an image.<br>";
$uploadOk = 0;
}
// Check if file already exists
if (file_exists($target_file))
{
echo "Sorry, file already exists.<br>";
$uploadOk = 0;
}
// if everything is ok, try to upload file
else
{
if (move_uploaded_file($_FILES["imageFileToUpload"]["tmp_name"], $target_file))
{
echo "The file ". basename( $_FILES["imageFileToUpload"]["name"]). " has been uploaded.<br>";
}
else
{
echo "Sorry, there was an error uploading your file.";
}
}
}
?>
I would like to thank everyone for their kind and patient help so far and I appreciate any answers and guidance.
UPDATE:
I am using an Ipad with Safari as well as an android device running 6.0.1 Marshmallow and the chrome browser. The dump file did show some information.
Here is the echo from the ipad:
RMA: 2468
C:\wamp64\www\upload.php:5:
array (size=5)
'name' => string 'image.jpg' (length=9)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 1
'size' => int 0
folder created at: uploads/2468
( ! ) Warning: getimagesize(): Filename cannot be empty in C:\wamp64\www\upload.php on line 31
Call Stack
# Time Memory Function Location
1 0.0006 376976 {main}( ) ...\upload.php:0
2 0.0011 377176 createImageFile( ) ...\upload.php:20
3 0.0012 377208 getimagesize ( ) ...\upload.php:31
File is not an image.
Sorry, there was an error uploading your file.
Android 6.0.1 chrome:
RMA: 1996
C:\wamp64\www\upload.php:5:
array (size=5)
'name' => string '20160322_125659.jpg' (length=19)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 1
'size' => int 0
folder created at: uploads/1996
( ! ) Warning: getimagesize(): Filename cannot be empty in C:\wamp64\www\upload.php on line 30
Call Stack
# Time Memory Function Location
1 0.0006 377880 {main}( ) ...\upload.php:0
2 0.0012 378096 createImageFile( ) ...\upload.php:20
3 0.0012 378128 getimagesize ( ) ...\upload.php:30
File is not an image.
Sorry, there was an error uploading your file.
Working echo from computer:
RMA: 1234
C:\wamp64\www\upload.php:5:
array (size=5)
'name' => string '58832_300x300.jpg' (length=17)
'type' => string 'image/jpeg' (length=10)
'tmp_name' => string 'C:\wamp64\tmp\phpF5F3.tmp' (length=25)
'error' => int 0
'size' => int 3801
The file 58832_300x300.jpg has been uploaded.
New record created successfully
It seems like it never sends the image type or the filesize, only the name when using mobile devices. Any ideas?
It seems to be a CORS problem.
There is an error when you try to upload from an another location.
See log file of your wamp server for the detailled error information...
For more informations of that mechanism, see : CORS wiki
Related
I am building a file upload tool for my website and am running into a strange issue. The html input is set up to accept image/png, image/jpg, image/jpeg, .pdf files and it works fine when I am using it to upload PDFs or images that came from a camera or a design software.
However, when I upload an image (png) that was a screenshot taken on my Mac, the $_FILES has a value for the name attribute, but has no values for the tmp_name, type, error, size attributes. I've tried renaming the file to see if that was the issue, and that doesn't appear to be the problem either.
This is the output I get when I run print_r($_FILES):
Array ( [fileupload] => Array ( [name] => Array ( [0] => Screen Shot 2020-12-23 at 2.10.06 PM.png ) [type] => Array ( [0] => ) [tmp_name] => Array ( [0] => ) [error] => Array ( [0] => 1 ) [size] => Array ( [0] => 0 ) ) )
Warning: mime_content_type(): Empty filename or path in pro_testupload.php on line 87
Warning: getimagesize(): Filename cannot be empty in pro_testupload.php on line 91
Warning: mime_content_type(): Empty filename or path in pro_testupload.php on line 103
Does anyone have any idea about what is going on here? Below is my code:
HTML Code
<form method="POST" action="_process/pro_testupload.php" enctype="multipart/form-data">
<input type="file" id="fileupload" name="fileupload[]" accept="image/png, image/jpg, image/jpeg, .pdf" multiple required>
<button class="btn waves-effect black waves-light" type="submit">Upload</button>
</form>
PHP Code
// -----------------------------------------------------------------
// FILE FORMAT CHECKING FUNCTIONS
// -----------------------------------------------------------------
function check_image($filename) {
// Check mime type using PHPs own built in functions (as client side mime type is vulnerable to exploitation)
$mime_type = mime_content_type($filename);
$allowed_file_types = ['image/png', 'image/jpeg', 'image/jpg'];
// Check the file is actually an image
$check = getimagesize($filename);
// Perform all checks
if (in_array($mime_type, $allowed_file_types) && is_array($check) !== False) {
return True;
} else {
return False;
}
}
function check_pdf($filename) {
// Check mime type using PHPs own built in functions (as client side mime type is vulnerable to exploitation)
$mime_type = mime_content_type($filename);
$allowed_file_types = ['application/pdf'];
// Perform checks
if (in_array($mime_type, $allowed_file_types)) {
return True;
} else {
return False;
}
}
// -----------------------------------------------------------------
// CHECK FILES TO ENSURE THEY MEET REQUIREMENTS
// -----------------------------------------------------------------
if(!empty(array_filter($_FILES['fileupload']['name']))) {
foreach ($_FILES['fileupload']['tmp_name'] as $key => $value) {
if (!(check_image($_FILES['fileupload']['tmp_name'][$key]) || check_pdf($_FILES['fileupload']['tmp_name'][$key]))) {
echo ("The files do not meet the uploaded file requirements");
exit;
}
}
} else {
echo ("There were no files requested to be uploaded.");
exit;
}
I'm trying to download a file from my website to my server but can't find why or where I'm doing that wrong.
Here my php code :
$fn = $_FILES['file']['name'];
if (is_writable('.')) {
echo "Writable<BR>";
} else {
echo "Not writable<BR>";
}
$upfile = './'.basename($fn);
echo $upfile.'<BR>';
shell_exec("echo 'baaaaah' > test.baaaah");
$f = $_FILES['file']['tmp_name'];
echo $f.'<BR>';
if (is_uploaded_file($f)) { echo "uploaded<BR>"; } else { echo "not uploaded<BR>";}
$com = "test - f ".$f." && echo 'F' || echo 'N'";
echo $com.'<BR>';
echo shell_exec($com).'<BR>';
if (move_uploaded_file($f,$uploadfile)) {
echo "File transfer OK<BR>";
} else {
echo "File transfer NOK<BR>";
}
print_r($_FILES);
And here the website output :
Writable
./flag.jpg
/tmp/phpyKvhEz
uploaded
test - f /tmp/phpyKvhEz && echo 'F' || echo 'N'
N
File transfer NOK
Array ( [file] => Array ( [name] => flag.jpg [type] => image/jpeg [tmp_name] => /tmp/phpyKvhEz [error] => 0 [size] => 1660 ) )
So first thing I check if my folder is writable (it's not intended to be '.' but I moved to here because the folder I want wasn't working either (same behavior as '.' through...)) => check
Then I try to shell_exec a file here juste to be sure => check, file is on server
Then I check if the temp file is created on the server :
- check, anyway is_uploaded thinks the file is here
- not check, but a test on the temp file doesn't work (and since the file is not supposed to be removed before the end of the script it should see the file here imho ?)
Then I try to make the move_uploaded_file => not check
And I print the $_FILES who shows nothing suspicious (error = 0, file names matches what I see before).
I can't figure what goes wrong nor where a mistake can come from ><
$uploadfile is undefined in your code. Change it or set it to '.' and it should work.
Got a script I've used several times, using move_uploaded_file. But what I can't figure out is why it do not respond in any way, no error reports, nothing.
<form> using method="post", target="upload" that is an <iframe>
action="file.php" responds to $_FILES
Correct enctype
Filerights is set to 777
Upload folder "uploads" exists
print_r($_FILES['file']) gives me:
Array
(
[name] => 1392930853.png
[type] => image/png
[tmp_name] => /tmp/php0rZdBf
[error] => 0
[size] => 611
)
The code below illustrates my script, and what I've figured out is that the last line with move_uploaded_file is the cause of my problem as it do not respond at all. As I wrote above, no error, no nothing.
Pastebin to script: http://pastebin.com/49m9Siqi
Got a clue what could be the cause of this?
$destination_path = getcwd().'/uploads/';
//echo $destination_path;
// File handling
$counted = count($_FILES['file']['name']);
$counted = $counted-1;
for ($i=0; $i<=$counted; $i++) {
if ($_FILES['file']['error'][$i] == UPLOAD_ERR_OK) {
$md5file = rand() . rand() . md5($_FILES['file']['name'][$i]) . rand() . rand();
if(move_uploaded_file($_FILES['file']['tmp_name'][$i], $destination_path . $md5file . "." . basename($_FILES['file']['type'][$i]))) { echo 'THIS WILL NOT BE ECHOED OUT ON THE PAGE'; }}}
There was a simple error in my form, as I handle my uploaded files like an array I need to create the array first.... Which I forgot to do in my form.
Wrong
<input type="file" name="file">
Correct
<input type="file" name="file[]">
I a php script which is called from a file form and it is supposed to check the form for password, filename, filetype and errors uploading to temp. If it passes all tests it's supposed to upload using move_uploaded_file but this does not work. No errors are outputted but I know it passes all the tests otherwise it would return back to the page.
PHP script:
<?php
$temp = explode(".", $_FILES["file"]["name"]);
if ($_POST["pass"] == "examplePass"){
if($_FILES["file"]["name"] == ""){
header("Location: /upload?i=f");
}
elseif($_FILES["file"]["type"] != "application/x-shockwave-flash"){
header("Location: /upload?i=s");
}
elseif ($_FILES["file"]["error"] > 0){
header("Location: /upload?i=e");
}
else{
move_uploaded_file($_FILES["file"]["tmp_name"], "/swf/". $_FILES["file"]["name"]);
if(file_exists("/swf/" . $_FILES["file"]["name"])){
header("Location: /upload?i=o");
}
else{
print_r($_FILES);
}
}
}
else{
header("Location: /upload?i=p");
}
?>
This outputs:
Array ( [file] => Array ( [name] => launcher.swf [type] => application/x-shockwave-flash [tmp_name] => /tmp/phpBugtQL [error] => 0 [size] => 161303 ) )
I have tried this with multiple swf files and I can remember it used to work.
I have set the whole of my web folder to 0777 and also recursed this into all sub-directories and files.
The directory /swf/ is at root so that is the absolute path.
Thanks in advance, Kyle
You can try using, ../swf/ or full path of the swf folder instead of /swf/
move_uploaded_file($_FILES["file"]["tmp_name"], "../swf/". $_FILES["file"]["name"]);
Reason for swf folder path, make sure you have used the correct path
Working on a little upload script here. I'm trying to check if the uploaded image really is an image and not just a renamed PHP file.
When the script is posted I can print the array with
foreach ($_FILES['images']['name'] as $key => $value){
print_r(getimagesize($_FILES['images']['tmp_name'][$key]));
That works just fine, so it won't return false. But even if I upload a file that is not an image, it won't give false. It just returns nothing at all, and the rest of my script just processes the thing like an image.
Could anyone tell me what I am doing wrong?
Upload
you can not use getimagesize on $_FILES['images']['tmp_name'][$key] directly .. you need to copy it into your system first before you can use it
Use $_FILES['images']['size'][$key] temporarily
Or
move_uploaded_file($_FILES['images']['tmp_name'][$key], $destination);
print_r(getimagesize($destination));
Fake Image
Please not that $_FILES['images']['type'][$key] can be faked
Using Fake image Headers
Example
file_put_contents("fake.png", base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABGdBTUEAALGPC/xhBQAAAAZQTFRF////
AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH0gQCEx05cq
KA8gAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII='));
Uploading fake.png
array
'name' =>
array
0 => string 'fake.png' (length=8)
'type' =>
array
0 => string 'image/png' (length=9)
'tmp_name' =>
array
0 => string 'C:\Apache\xampp\tmp\php44F.tmp' (length=30)
'error' =>
array
0 => int 0
'size' =>
array
0 => int 167
Validate Image
Usage
var_dump ( getimagesizeReal ( "fake.png" ) );
Function Used
function getimagesizeReal($image) {
$imageTypes = array (
IMAGETYPE_GIF,
IMAGETYPE_JPEG,
IMAGETYPE_PNG,
IMAGETYPE_SWF,
IMAGETYPE_PSD,
IMAGETYPE_BMP,
IMAGETYPE_TIFF_II,
IMAGETYPE_TIFF_MM,
IMAGETYPE_JPC,
IMAGETYPE_JP2,
IMAGETYPE_JPX,
IMAGETYPE_JB2,
IMAGETYPE_SWC,
IMAGETYPE_IFF,
IMAGETYPE_WBMP,
IMAGETYPE_XBM,
IMAGETYPE_ICO
);
$info = getimagesize ( $image );
$width = #$info [0];
$height = #$info [1];
$type = #$info [2];
$attr = #$info [3];
$bits = #$info ['bits'];
$channels = #$info ['channels'];
$mime = #$info ['mime'];
if (! in_array ( $type, $imageTypes )) {
return false; // Invalid Image Type ;
}
if ($width <= 1 && $height <= 1) {
return false; // Invalid Image Size ;
}
if($bits === 1)
{
return false; // One Bit Image .. You don't want that ;
}
return $info ;
}
I'd like to recommend against trusting the results of getimagesize() when deciding whether to place the uploaded file anywhere in your document root. That's because PHP code embedded in GIF files (titled like image.gif.php) will be identified as images by getimagesize(), but serving them will run the PHP code inside them in addition to displaying the image. Here is some more information on the issue.
The article linked above recommends setting up a separate controller through which all the user uploaded files are served. Files read with readfile() are not parsed when accessed through the local filesystem.
Firstly, you can use getimagesize on $_FILES['images']['tmp_name'], so that's not an issue.
If you want to check if the file is an image, then try this:
if(isset($_POST['submit'])) {
$check = getimagesize($_FILES['images']['tmp_name']);
if($check !== false) {
echo 'File is an image - ' . $check['mime'];
}
else {
echo 'File is not an image';
}
}
You can simply use $_FILES['images']['type'] . it'll give you the type of file uploaded. Then check it againt octate stream or other executable file. If so then do not allow it.
#user1362916 If you are uploading multiple images with HTML then perhaps you need to add one more array like this.
if(isset($_POST['submit'])) {
$check = getimagesize($_FILES['images']['tmp_name'][$i]);
if($check !== false) {
echo 'File is an image - ' . $check['mime'];
}
else {
echo 'File is not an image';
}
}
Here check [i] because this is for multiple file upload.
Below is full script
<!DOCTYPE html>
<html>
<body>
<form action="#" method="post" enctype="multipart/form-data">
Select image to upload:
<input name="my_files[]" type="file" multiple="multiple" />
<input type="submit" value="Upload Image" name="submit">
</form>
<?php
if (isset($_FILES['my_files']))
{
$myFile = $_FILES['my_files'];
$fileCount = count($myFile["name"]);
for ($i = 0; $i <$fileCount; $i++)
{
$error = $myFile["error"][$i];
if ($error == '4') // error 4 is for "no file selected"
{
echo "no file selected";
}
else
{
if(isset($_POST['submit'])) {
$check = getimagesize($_FILES['my_files']['tmp_name'][$i]);
if($check !== false) {
echo 'File is an image - ' . $check['mime'];
}
else {
echo 'File is not an image';
}
}
}
}
}
?>
</body>
</html>