Upload error - file is not writable - php

I want to upload multiple files to the server.
As far as I can see files are not writable.
What can I do so my code can actually work and upload files.
PHP:
if(isset($_FILES ['uploaded_files']))
{
foreach($_FILES['uploaded_files']['name'] as $key=>$value)
{
if(is_uploaded_file($_FILES['uploaded_files']['tmp_name'][$key]) && $_FILES['uploaded_files']['error'][$key] == 0)
{
$filename = $_FILES['uploaded_files']['name'][$key];
if (is_writable($filename)) {
echo 'The file is writable';
} else {
echo 'The file is not writable';
}
if(move_uploaded_file($_FILES['uploaded_files']['tmp_name'][$key], '../images/gallery'. $filename))
{
//code
}
else
{
die ('There was a problem uploading the pictures.');
}
}
else
{
die ('There is a problem with the uploading system.');
}
}
}
HTML:
<form enctype="multipart/form-data" action="upload.php" method="POST">
<input type="hidden" id="input_clone_id" name="input_clone_id" value="'.$row['id'].'"/>
<input type="hidden" id="input_clone_var" name="input_clone_var" value="V"/>
<input type="file" name="uploaded_files[]" id="input_clone" multiple="multiple" /><br />
<input type="submit" style="margin-left:0" value="Upload Files" />
</form>

I see two problems with this. The first is a security issue and the second is probably what is causing your problem
You have a security problem here:
$filename = $_FILES['uploaded_files']['name'][$key];
...
if(move_uploaded_file($_FILES['uploaded_files']['tmp_name'][$key], '../images/gallery'. $filename))
...
Problem a: Since $filename comes from the $_FILES array, it CANNOT be trusted. The user told your site what the name of their file was and put it there. They could feed you some bogus filename that could cause your script to fail in interesting ways. You need to sanitize that filename before using it in any way.
Problem b: By allowing the user to specify the filename, they could potentially overwrite other files in your "images/gallery" directory simply by specifying a conflicting filename. The way to avoid this is to use a database, generate a unique identifier for the uploaded file, store the file under that unique name, and in the database keep a record of the original filename and other information. That way you always know what the original filename was and you don't have the chance of someone trying to overwrite files in that directory.
Writing problem:*
Your "check for writable" statement is wrong. The filename that comes back is the one that the user used when submitting. This will not point to any point on your filesystem...it points to a spot on theirs (sometimes) which you cannot see. What you need to check is that your "../images/gallery" directory is writable rather than $filename. If that fails, you need to do either "chmod -R 777 gallery" while in the images folder if you have command line access or give it world write access through whatever FTP client you are using if you are using FTP to talk to your server.
So, what you should have instead for that check is:
if (is_writable("../images/gallery")) {
echo 'The file is writable';
} else {
echo 'The file is not writable';
}
After doing that, if your script comes back and says "the file is writable", it should have been able to copy the file into your images/gallery folder (remember to not use the name of the file the user gave you). If not, perhaps you don't have permissions to move uploaded files.
As for the location of uploaded files, I think sometimes they are deleted after the script execution ends sometimes, but if not, you can echo the 'tmp_name' of the file and if you go to that directory you should find it sitting there. That would be just a verification test to make sure the file was actually getting to your server. So long as you have write permissions (that what chmod 777 does) on the directory you are moving the uploaded file to, you should be able to copy it there.

You are checking to see if a file that you recently uploaded, but not yet saved is writable, I don't think such a file will ever be writable.
Better remove that if, or just check if the folder you are uploading to is writable.
Other than that, I checked your code and it works.

Related

Permission issues viewing photos uploaded with php

I'm following a tutorial for uploading image files using php on udemy. I can choose an image and upload it to a folder without any problems.
When I click on the image after it has been uploaded to the folder, windows photo viewer says: "photo.png It appears that you don't have permission to view this file. Check the permissions and try again".
When I checked permissions it said "You must have read permissions to view the properties of this file".
I used the chmod function set to 0755, which allows the owner to read and write, and lets everyone else read it. I tried changing the chmod codes but it didn't help.
I'm thinking it has something to do with my server permissions, but can't find any solution on google. My images are uploaded to Abyss Web Server.
Here is the code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
function upload_file() {
//setup
$tmp_name = $_FILES['file']['tmp_name'];
$target_dir = 'uploads/';
$target_file = $target_dir . basename($_FILES['file']['name']);
$max_file_size = 5000000; //5mb
$allowed_file_types = array('application/pdf; charset=binary');
$allowed_image_types = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG);
//check if image type is allowed
$image_check = getimagesize($tmp_name);
if(! in_array($image_check[2], $allowed_image_types)) {
//if not allowed image check if allowed file type
exec('file -bi' . $tmp_name, $file_check);
if(! in_array($file_check[0], $allowed_file_types)) {
return 'This file type is not allowed';
}
}
//check if file already exists
if(file_exists($target_file)) {
return 'Sorry that file already exists';
}
//check file size
if(file_exists($target_file)) {
return 'Sorry this file is too big';
}
//store the file
if(move_uploaded_file($tmp_name, $target_file)) {
chmod($target_file, 0644);
return 'Your file was uploaded';
}
else {
return 'There was a problem storing your file. Try again?';
}
}
if(! empty($_FILES)) {
echo upload_file();
}
?>
<form action="" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="file">
<input type="submit" Value="upload">
</form>
Since loading the file using a custom made HTML page specifically for testing motives does show the image correctly, then it's most likely a hotlink protection issue. (This was found out after a few comments to the question).
In cPanel, for example, there is a tool to manage this feature and it revolves around the usage of a file called .htaccess. This file is used for a lot of things in the web development world.
Some people don't like their copyrighted images to be accessed, so one way to avoid inexperienced people (let's say, "people in userland") from doing that is to enable this protection. This works for any given file extension that you set it up to.
One way to address this issue is to go to cPanel and disable (or modify accordingly) the Hotlink Protection feature. Another way, is to find the .htaccess file that is causing the issue, which requires understanding the way it works and the syntax it uses.

PHP upload files to remote server

I am completely a novice in all this ...
I have created a Social Networking project in which there is a module which allows user to upload photos..
I have hosted this project in my college server
I access that server using bitvise client with my server credentials.
My problem is i don't know how to setup upload mechanism for remote server ... In my localhost i simply use
move_uploaded_file($_FILES['file']['tmp_name'],$target_file);
function but i don't know how to do this for remote server ...
I tried FTP by looking at some tutorials but that didn't worked for me.
In my project structure there is a directory
users/user_id (diff for all users)/photos
here i want to place the uploaded files....
A proper description with example and proper functioning might be very helpful for me.... Thank you
EDIT:
Below is my code.
Photos.php
<form class="input-group-btn" method="post" action="editPhotos.php"enctype="multipart/form-data" id="myForm">
<input type="file" name="file" id="imgInp">
<button type="submit" class="btn btn-primary" name="form-submit">Done</button>
</form>
editPhotos.php
if( isset($_POST['form-submit']) ){
$target_file = "users/".$email."/pictures/Photos/" . basename($_FILES["file"]["name"]);
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
move_uploaded_file($_FILES['file']['tmp_name'],$target_file);
$img =str_replace(" ", "",basename($_FILES["file"]["name"]));
rename($target_file, "users/".$email."/pictures/Photos/".$img);
header('Refresh: 1; url=Photos.php?user='.$email);
}
Small tutorial how to upload file.
For sure, you need correct encryption and file's type in your form (ommited other fields, to clear example):
form.html
< form action="upload.php" method="post" enctype="multipart/form-data">< /form>
< input name="test" type=file>
upload.php
In $_FILES you have all data of uploaded file. In given example, we have field named test.
Advice, to always first check error $_FILES['test']['error'] - the values you can find in here.
If this is correct, then prepare upload path. Some advices:
remember that if you use original filename ($_FILES['test']['name']), then is User upload second file, with same name, you will need overwrite file or ignore upload. Other way, is to save data to database and generate temporary name form him.
destination path(target_file) - regardless if upload folder is in the same catalog, you should always use global path, as good practice. You can use DIR for that.
don't use in path data, like email - is you have project, and want give opportunity to change email in configuration, what you will do with files? Better save user to Database and use his ID as key.
If you have path, then you simply need only use of move_uploaded_file, but remember to check result, as it not always will return true. You can have error, when you don't have permissions to destination folder (you'll need debug this).
I see that you, first upload file, then rename (then you should check, if rename was success). Don't extends this process, if it not necessary. Upload file for final path and name.
Example of code (I this rattle off)
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
$fileName = basename($_FILES["file"]["name"]);
$fileName = str_replace(" ", "", $fileName);
$target_file = sprintf(__DIR__ . "/users/%s/pictures/Photos/%s", $email, $fileName);
if (move_uploaded_file($_FILES['file']['tmp_name'], $target_file)) {
// File was uploaded
header('Refresh: 1; url=Photos.php?user=' . $email);
} else {
// File was not uploaded;
throw new \Exception('File was not uploaded. Check warnings.');
}
}
Used other method to check, if this is POST
use method sprintf, for better code quality
checked effect of move_uploaded_file
use global path for destination file
Below code is risky in live environment, please use cautiously
Use a relative path to the uploads folder. For example, if your uploads folder is placed outside your current folder. Then
$PATH = '/absolute/example/path/to/uploads';//from config file
$target_file = "$PATH/file_name";
move_uploaded_file($_FILES['file']['tmp_name'],$target_file);
The above code will work both in local and remote server.
Other checks are below:
Check for errors while uploading file in server
To enable error handling use below code in your upload logic:
ini_set('display_errors', 1);
error_reporting(E_ALL);
Another important note is to make uploads folder writable otherwise file upload wont work.

Error during uploading a file with php

Ok, I used google over the last 2 days and didn't got what is wrong with my code. First it seemed that I used the wrong path but the official "Hilfe Center" (like helping center or so) from 1&1 said that this must be the right path "e:\Kunden\Homepages\11\d12345678\www\UploadTest" (obviously you have to adapt it to your path, which i got throught phpinfo() )
so I'm using the following code:
<form action=\"upload.php\" method=\"post\" enctype=\"multipart/form-data\">
<input type=\"file\" name=\"datei\"><br>
<input style=\"position:absolute;left:5px\" type=\"submit\" value=\"Hochladen\">
</form>
on the site where you upload the file and
$max_filesize = 524288; // Maximum filesize in BYTES (currently 0.5MB).
$upload_path = "e:\\Kunden\\Homepages\\11\\d12345678\\www\\UploadTest";
$filename = $_FILES['userfile']['name']; // Get the name of the file (including file extension).
if(filesize($_FILES['userfile']['tmp_name']) > $max_filesize)
die('The file you attempted to upload is too large.'); // if we upload large file then we get error.
if(!is_writable($upload_path))
die('You cannot upload to the specified directory, please CHMOD it to 777.'); // if we have no enough permission then got error.
if(move_uploaded_file($_FILES['userfile']['tmp_name'],$upload_path . $filename)){
// if everything is fine then we upload file and go to somewhere else
header ('location: whereeveryouwantogo.php');
} else {
echo 'There was an error during the file upload. Please try again.';
}
on the site where the php script is running (upload.php). I got the code on another thread here and wanted to use it for troubleshooting. Later I'm going back to my own code.
I am now at the last error:
'There was an error during the file upload. Please try again.';
I just want to upload .txt files that are later used on a news based site. Thx for any helps in advance!
I think the problem is name of the input or name of the files variable.
$files=$_FILES['datei']['tmp_name'];

PHP File Copy() Not working on IIS 6

I have the following code that attempts to take a users form input of a file, and upload it to the webserver.
This code does work on a Apache server, however I'm now trying to get the same code working on my Windows IIS 6 web server, which has PHP (Version 5.2.3) installed and working. I have set the PHP.INI file so that
file_uploads = On
upload_tmp_dir = "C:\Temp"
My form is
<form method="POST" action="do_upload.php" enctype="multipart/form-data">
<input type="file" name="img1" size="30">
<input type="submit" name="BtnUpload" value="Click To Upload Now">
</form>
My PHP code to do the upload is
$abpath = "C:\MyWebs\Website1\httdocs\images";
#copy($img1, "$abpath/$img1_name") or $log .= "Couldn't copy image 1 to server";
if (file_exists("$abpath/$img1_name"))
{
$log .= "File 1 was uploaded";
}
else
{
$log .= "File 1 is not an image";
}
For some reason when I check the value of $img1 e.g echo $img1; it is empty. Therefore I tried to get the file using $_FILES['img1']['name']. This worked fine, but still I couldn't upload any files
Any ideas why this is happening.
Your code should be:
move_uploaded_file($_FILES['img1']['tmp_name'], "$abpath/$img1_name");
Don't copy() uploaded files. There are a few edge cases where an uploaded file can be tampered with, which is why move_uploaded_file() exists - it checks for those particular types of tampering.
As well, be VERY careful with how you create your filenames when processing the upload. If you directly use ANYTHING provided in $_FILES as part of the destination path/name for the file, you are opening bad security holes on your server, and a malicious user can exploit that to scribble a file anywhere they want on your server.

How to upload file to amazon s3 using MAMP?

I'm trying to push a file to a Amazon s3 filebucket.
I'm posting the file through an html form.
I try to generate a path to the file like this($file is a part of a foreach, because i need to support multiple files in a form-submit.)
$file['tmp_name'].'/'.$file['name'];
this outputs a filepath like this
/Applications/MAMP/tmp/php/phpZDcVQv/pdf.pdf
/Applications/MAMP/tmp/php/ exists, but nothing is inside it. I have set access read and write for everyone to that folder.
I use a library to post the images to Amazon: https://github.com/tpyo/amazon-s3-php-class It also complains that the filepath i have provided doesn't exist. It's running a check like:
if (!file_exists($file) || !is_file($file) || !is_readable($file))
How come the files aren't added?
Am I referencing the wrong folder? The file with the code is in /web/projectname/
Someone on the internet said something unclear about php removing the temp-file directly. Is this after the response has been run? Do I need to address this in some way?
The most simple code that generates the problem:
foreach ($_FILES as $file) {
$filepath = $file['tmp_name'].'/'.$file['name'];
if(file_exists($filepath)){
echo 'true <br />';
}else{
echo 'false <br />';
}
}
This echo:es false even if files have been uploaded.
$filepath contains the path i described above.
as the manual states:
$_FILES['userfile']['tmp_name']
The temporary filename of the file in which the uploaded file was stored on the server.
and
$_FILES['userfile']['name']
The original name of the file on the client machine.
this means that file_exists($file['tmp_name']) should be true.
The path $file['tmp_name'].'/'.$file['name'] is bogus, since $file['name'] is there only for informing you of the original name, but this name is not used while saving the uploaded file on the server.
So in your example /Applications/MAMP/tmp/php/phpZDcVQv is actually the uploaded file.

Categories