I am trying to upload a file to a server using AS3 and PHP. Here is my AS3 Code and then the PHP code. The folder I am trying to upload to is writable. and the file size is about 20Kb. The php script is on my server, and the flash file calls it.
var UPLOAD_URL: String ="linktophpscriptonMysite"
var fr: FileReference;
var request: URLRequest = new URLRequest();
request.url = UPLOAD_URL;
function startThis(): void {
fr = new FileReference();
fr.addEventListener(Event.SELECT, selectHandler);
fr.addEventListener(Event.OPEN, openHandler);
fr.addEventListener(ProgressEvent.PROGRESS, progressHandler);
fr.addEventListener(Event.COMPLETE, completeHandler);
fr.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
startUpload()
}
function startUpload(): void {
try {
var success: Boolean = fr.browse();
trace("success")
} catch (error: Error) {
trace("Unable to browse for files.", Error);
}
}
function progressHandler(event: ProgressEvent): void {
trace(event.bytesLoaded, event.bytesTotal);
}
function ioErrorHandler(event: IOErrorEvent): void {
//trace("Some error ", event.target.data.systemResult);
//systemResult is echoed by PHP
}
function openHandler(event: Event): void {
try {
//var success: Boolean = fr.browse();
} catch (error: Error) {
trace("Unable to browse for files.", Error);
}
}
function completeHandler(event: Event): void {
trace(event.target.data.systemResult);
//this reads the result, again, from PHP echo "systemResult=all is good";
}
function selectHandler(event: Event): void {
fr.upload(request);
}
And then, here is the php code: This code is a general upload script I found on the php manual site
<?php
header('Content-Type: text/plain; charset=utf-8');
try {
// Undefined | Multiple Files | $_FILES Corruption Attack
// If this request falls under any of them, treat it invalid.
if (
!isset($_FILES['upfile']['error']) ||
is_array($_FILES['upfile']['error'])
) {
echo "systemResult=Error";
throw new RuntimeException('Invalid parameters.');
}
// Check $_FILES['upfile']['error'] value.
switch ($_FILES['upfile']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
default:
throw new RuntimeException('Unknown errors.');
}
// You should also check filesize here. max is 100 mb
if ($_FILES['upfile']['size'] > 10000000) {
throw new RuntimeException('Exceeded filesize limit.');
}
// DO NOT TRUST $_FILES['upfile']['mime'] VALUE !!
// Check MIME Type by yourself.
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['upfile']['tmp_name']),
array(
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
),
true
)) {
throw new RuntimeException('Invalid file format.');
}
// You should name it uniquely.
// DO NOT USE $_FILES['upfile']['name'] WITHOUT ANY VALIDATION !!
// On this example, obtain safe unique name from its binary data.
if (!move_uploaded_file(
$_FILES['upfile']['tmp_name'],
sprintf('./uploads/%s.%s',
sha1_file($_FILES['upfile']['tmp_name']),
$ext
)
)) {
throw new RuntimeException('Failed to move uploaded file.');
}
echo 'File is uploaded successfully.';
} catch (RuntimeException $e) {
echo $e->getMessage();
}
?>
The problem I am having is that the file does not get uploaded, and I dont get any feedback from php as to why.
Thank you for any help
UPDATE:
Thank you #akmozo for the reply and answer. Like I said in my comment, this script worked
<?php
$uploads_dir = './uploads/';
if( $_FILES['Filedata']['error'] == 0 ){
if( move_uploaded_file( $_FILES['Filedata']['tmp_name'], $uploads_dir.$_FILES['Filedata']['name'] ) ){
echo 'ok';
echo 'systemResult=Awesome';
exit();
}
}
echo 'error';
echo 'systemResult=did not work';
exit();
?>
By default, the upload data field name of a FileReference object is "Filedata" and that's what you should use in your PHP code ( $_FILES['Filedata'] ...).
You can of course change that name in the FileReference.upload() function :
fr.upload(request, 'upfile');
Hope that can help
Related
I am getting data from a database and I want to check whether the data contains an image or not. I tried with following code and I want to know if is this a good solution for this.
$headers = get_headers('https://cdn.discordapp.com/attachments/999921405858680857/1011168600410820679/1656572127-blog-2.JPG', 1);
if (strpos($headers['Content-Type'], 'image/') !== false) {
echo "Work";
} else {
echo "Not Image";
}
No. When verifying files, you should never rely on headers. Headers can easily be modified by whomever is providing you with the file. A much more reliable option would be to use the PHP fileinfo extension.
<?php
// Fileinfo extension loaded
$finfoAvailable = false;
// Download the file
$imgUrl = 'https://cdn.discordapp.com/attachments/999921405858680857/1011168600410820679/1656572127-blog-2.JPG';
// Use basename() function to return the base name of file
$file_name = basename($imgUrl);
// Get the file with file_get_contents()
// Save the file with file_put_contents()
if (file_put_contents($file_name, file_get_contents($imgUrl)))
{
// Checks if fileinfo PHP extension is loaded.
if (!extension_loaded('fileinfo'))
{
// dl() is disabled in the PHP-FPM since php7 so we check if it's available first
if(function_exists('dl')
{
// Check if OS is Windows
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
{
if (!dl('fileinfo.dll'))
{
echo "Unable to load fileinfo.dll extension";
}
else
{
$finfoAvailable = true;
}
}
// OS is something else than Windows (like linux)
else
{
if (!dl('fileinfo.so'))
{
echo "Unable to load fileinfo.so extension";
}
else
{
$finfoAvailable = true;
}
}
}
else
{
echo "Unable to load PHP extensions as dl() function is not available";
}
}
else
{
$finfoAvailable = true;
}
// If fileinfo is available
if($finfoAvailable)
{
$finfo = finfo_open( FILEINFO_MIME_TYPE );
$mtype = finfo_file( $finfo, $file_name );
if(strpos($mtype, 'image/') === 0)
{
echo "File is an image";
}
else
{
echo "File is not an image";
}
}
else
{
echo "PHP extension fileinfo in not available";
}
}
else
{
echo "File downloading failed.";
}
?>
Christian pleasure.
I start with telling you: "sorry for my english but in years of studies i don't speak very well".
Anyway....
I've a website developed with design pattern MVC, in this website the user can upload php file and run his. For using this file uploaded, the user have an a token: example.com/home/profile/advance?token=XXXXXXXXXXXXXX
I would that this file uploaded from user can't interact with my server as if it were inside a virtual machine.
It possible?
I hope I explained myself.
That's absolute possible. Just append the user's token to your form uploader:
<?php
$token = 'xxx';
?>
<form action="home/profile/advance?token=<?php echo htmlentities(urlencode($token)); ?>" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload File" name="submit">
This will make a $_POST to home/profile/advance?token=xxx.
Note that a server-side generated token should only contain alphanumeric characters, but it's best to wrap it in htmlentities() and urlencode() to be safe.
However, note that allowing users to upload (and run) their own PHP files is a huge security risk! I would strongly recommend not allowing them to run PHP, but instead limiting allowed uploads to raw .txt files. There's several different vectors to consider here, so I would recommend implementing the following (courtesy of CertaiN, with minor modification):
<?php
header('Content-Type: text/plain; charset=utf-8');
try {
// Undefined | Multiple Files | $_FILES Corruption Attack
// If this request falls under any of them, treat it invalid.
if (
!isset($_FILES['upfile']['error']) ||
is_array($_FILES['upfile']['error'])
) {
throw new RuntimeException('Invalid parameters.');
}
// Check $_FILES['upfile']['error'] value.
switch ($_FILES['upfile']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
default:
throw new RuntimeException('Unknown errors.');
}
// You should also check filesize here.
if ($_FILES['upfile']['size'] > 1000000) {
throw new RuntimeException('Exceeded filesize limit.');
}
// DO NOT TRUST $_FILES['upfile']['mime'] VALUE !!
// Check MIME Type by yourself.
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['upfile']['tmp_name']),
array(
'txt' => 'text/plain',
),
true
)) {
throw new RuntimeException('Invalid file format.');
}
// You should name it uniquely.
// DO NOT USE $_FILES['upfile']['name'] WITHOUT ANY VALIDATION !!
// On this example, obtain safe unique name from its binary data.
if (!move_uploaded_file(
$_FILES['upfile']['tmp_name'],
sprintf('./uploads/%s.%s',
sha1_file($_FILES['upfile']['tmp_name']),
$ext
)
)) {
throw new RuntimeException('Failed to move uploaded file.');
}
echo 'File is uploaded successfully.';
} catch (RuntimeException $e) {
echo $e->getMessage();
}
I'm trying to upload an Excel file using CodeIgniter. What I want to do is to just read the file without moving/uploading it in my upload path which is required in the configuration.
Yup, I can use the native PHP's $_FILES superglobal variable. But, I like to use the library because it gives me extra security to my app.
So.. how can I upload a file using CI's File Uploading class without being uploaded to my server?
$config['upload_path'] = './public/uploads/';
$config['allowed_types'] = 'xlsx|xls';
$this->load->library('upload', $config);
if(!$this->upload->do_upload('userfile'))
{
$this->output->set_output(array('result' => FALSE, 'message' => $this->upload->display_errors()))->_display();
exit(1);
}
else
{
$data = $this->upload->data();
// Let the model do his work!
$this->load->model('Userlist_Model');
$result = $this->Userlist_Model->extract_list($data);
$this->output->set_output($result)->_display();
}
Here's my solution: Just extend the Upload.php (CI_Upload) by creating MY_Upload inside the libraries folder. Copying the do_upload() method then remove the part where the upload starts:
MY_Upload.php
class MY_Upload extends CI_Upload
{
public function validate_file($field = 'userfile')
{
// Is $_FILES[$field] set? If not, no reason to continue.
if (isset($_FILES[$field]))
{
$_file = $_FILES[$field];
}
// Does the field name contain array notation?
elseif (($c = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $field, $matches)) > 1)
{
$_file = $_FILES;
for ($i = 0; $i < $c; $i++)
{
// We can't track numeric iterations, only full field names are accepted
if (($field = trim($matches[0][$i], '[]')) === '' OR ! isset($_file[$field]))
{
$_file = NULL;
break;
}
$_file = $_file[$field];
}
}
if ( ! isset($_file))
{
$this->set_error('upload_no_file_selected', 'debug');
return FALSE;
}
// Is the upload path valid?
if ( ! $this->validate_upload_path())
{
// errors will already be set by validate_upload_path() so just return FALSE
return FALSE;
}
// Was the file able to be uploaded? If not, determine the reason why.
if ( ! is_uploaded_file($_file['tmp_name']))
{
$error = isset($_file['error']) ? $_file['error'] : 4;
switch ($error)
{
case UPLOAD_ERR_INI_SIZE:
$this->set_error('upload_file_exceeds_limit', 'info');
break;
case UPLOAD_ERR_FORM_SIZE:
$this->set_error('upload_file_exceeds_form_limit', 'info');
break;
case UPLOAD_ERR_PARTIAL:
$this->set_error('upload_file_partial', 'debug');
break;
case UPLOAD_ERR_NO_FILE:
$this->set_error('upload_no_file_selected', 'debug');
break;
case UPLOAD_ERR_NO_TMP_DIR:
$this->set_error('upload_no_temp_directory', 'error');
break;
case UPLOAD_ERR_CANT_WRITE:
$this->set_error('upload_unable_to_write_file', 'error');
break;
case UPLOAD_ERR_EXTENSION:
$this->set_error('upload_stopped_by_extension', 'debug');
break;
default:
$this->set_error('upload_no_file_selected', 'debug');
break;
}
return FALSE;
}
// Set the uploaded data as class variables
$this->file_temp = $_file['tmp_name'];
$this->file_size = $_file['size'];
// Skip MIME type detection?
if ($this->detect_mime !== FALSE)
{
$this->_file_mime_type($_file);
}
$this->file_type = preg_replace('/^(.+?);.*$/', '\\1', $this->file_type);
$this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
$this->file_name = $this->_prep_filename($_file['name']);
$this->file_ext = $this->get_extension($this->file_name);
$this->client_name = $this->file_name;
// Is the file type allowed to be uploaded?
if ( ! $this->is_allowed_filetype())
{
$this->set_error('upload_invalid_filetype', 'debug');
return FALSE;
}
// if we're overriding, let's now make sure the new name and type is allowed
if ($this->_file_name_override !== '')
{
$this->file_name = $this->_prep_filename($this->_file_name_override);
// If no extension was provided in the file_name config item, use the uploaded one
if (strpos($this->_file_name_override, '.') === FALSE)
{
$this->file_name .= $this->file_ext;
}
else
{
// An extension was provided, let's have it!
$this->file_ext = $this->get_extension($this->_file_name_override);
}
if ( ! $this->is_allowed_filetype(TRUE))
{
$this->set_error('upload_invalid_filetype', 'debug');
return FALSE;
}
}
// Convert the file size to kilobytes
if ($this->file_size > 0)
{
$this->file_size = round($this->file_size/1024, 2);
}
// Is the file size within the allowed maximum?
if ( ! $this->is_allowed_filesize())
{
$this->set_error('upload_invalid_filesize', 'info');
return FALSE;
}
// Are the image dimensions within the allowed size?
// Note: This can fail if the server has an open_basedir restriction.
if ( ! $this->is_allowed_dimensions())
{
$this->set_error('upload_invalid_dimensions', 'info');
return FALSE;
}
// Sanitize the file name for security
$this->file_name = $this->_CI->security->sanitize_filename($this->file_name);
// Truncate the file name if it's too long
if ($this->max_filename > 0)
{
$this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);
}
// Remove white spaces in the name
if ($this->remove_spaces === TRUE)
{
$this->file_name = preg_replace('/\s+/', '_', $this->file_name);
}
if ($this->file_ext_tolower && ($ext_length = strlen($this->file_ext)))
{
// file_ext was previously lower-cased by a get_extension() call
$this->file_name = substr($this->file_name, 0, -$ext_length).$this->file_ext;
}
/*
* Validate the file name
* This function appends an number onto the end of
* the file if one with the same name already exists.
* If it returns false there was a problem.
*/
$this->orig_name = $this->file_name;
if (FALSE === ($this->file_name = $this->set_filename($this->upload_path, $this->file_name)))
{
return FALSE;
}
/*
* Run the file through the XSS hacking filter
* This helps prevent malicious code from being
* embedded within a file. Scripts can easily
* be disguised as images or other file types.
*/
if ($this->xss_clean && $this->do_xss_clean() === FALSE)
{
$this->set_error('upload_unable_to_write_file', 'error');
return FALSE;
}
/*
* Set the finalized image dimensions
* This sets the image width/height (assuming the
* file was an image). We use this information
* in the "data" function.
*/
$this->set_image_properties($this->upload_path.$this->file_name);
// Return true if the file passed the validation
return TRUE;
}
}
After trying different approaches, I couldn't find the cause of the issue...
I'm trying to upload an image (choosen from photo library) to store it on a linux webserver using a php script.
Here the Swift 4 code:
func uploadImage(imageFile: UIImage?){
let imageData = UIImageJPEGRepresentation(imageFile!, 0.5)!
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: "image", fileName: "test", mimeType: "image/jpg")
},
to: "http://XXX/images/upload.php", method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
if let result = response.result.value {
// Get the json response. From this, we can get all things we send back to the app.
//let JSON = result as! NSDictionary
//self.imageServerLocation = JSON.object(forKey: "filepath") as? String
debugPrint(response)
}
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
The code at the server where is the following:
<?php
if (empty($_FILES["image"])) {
// So we send a message back saying there is no data...
$response = array("error" => "nodata");
}else { // If there is data
$response['error'] = "NULL";
// Setup a filename for the file. Uniqid can be changed to anything, but this makes sure
// that every file doesn't overwrite anything existing.
$filename = uniqid() . ".jpg";
// If the server can move the temporary uploaded file to the server
if (move_uploaded_file($_FILES['image']['test'], '/default/' . $filename)) {
// Send a message back saying everything worked!
// I also send back a link to the file, and the name.
$response['status'] = "success";
$response['filepath'] = "https:" . $filename;
$response['filename'] = "".$_FILES["file"]["name"];
} else{
// If it can't do that, Send back a failure message, and everything there is / should be form the message
// Here you can also see how to reach induvidual data from the image, such as the name.
$response['status'] = "Failure";
$response['error'] = "".$_FILES["image"]["error"];
$response['name'] = "".$_FILES["image"]["name"];
$response['path'] = "".$_FILES["image"]["tmp_name"];
$response['type'] = "".$_FILES["image"]["type"];
$response['size'] = "".$_FILES["image"]["size"];
}
}
// Encode all the responses, and echo them.
// This way Alamofire gets everything it needs to know
echo json_encode($response);
?>
I get always the same error:
[Data]: 107 bytes
[Result]: SUCCESS: {
error = 0;
name = test;
path = "/tmp/php7iIqSv";
size = 43337;
status = Failure;
type = "image/jpg";
}
Can someone give me a hint to solve my problem?
Thanks in advance
I think you have error in move_uploaded_file function.You are giving key that is not there in $_FILES global
It should be like
move_uploaded_file($_FILES['image']['tmp_name'], '/default/' . $filename)
And make sure the folder/directory where you are moving the file is writable.
I do some form validation to ensure that the file a user uploaded is of the right type. But the upload is optional, so I want to skip the validation if he didn't upload anything and submitted the rest of the form. How can I check whether he uploaded something or not? Will $_FILES['myflie']['size'] <=0 work?
You can use is_uploaded_file():
if(!file_exists($_FILES['myfile']['tmp_name']) || !is_uploaded_file($_FILES['myfile']['tmp_name'])) {
echo 'No upload';
}
From the docs:
Returns TRUE if the file named by
filename was uploaded via HTTP POST.
This is useful to help ensure that a
malicious user hasn't tried to trick
the script into working on files upon
which it should not be working--for
instance, /etc/passwd.
This sort of check is especially
important if there is any chance that
anything done with uploaded files
could reveal their contents to the
user, or even to other users on the
same system.
EDIT: I'm using this in my FileUpload class, in case it helps:
public function fileUploaded()
{
if(empty($_FILES)) {
return false;
}
$this->file = $_FILES[$this->formField];
if(!file_exists($this->file['tmp_name']) || !is_uploaded_file($this->file['tmp_name'])){
$this->errors['FileNotExists'] = true;
return false;
}
return true;
}
This code worked for me. I am using multiple file uploads so I needed to check whether there has been any upload.
HTML part:
<input name="files[]" type="file" multiple="multiple" />
PHP part:
if(isset($_FILES['files']) ){
foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
if(!empty($_FILES['files']['tmp_name'][$key])){
// things you want to do
}
}
#karim79 has the right answer, but I had to rewrite his example to suit my purposes. His example assumes that the name of the submitted field is known and can be hard coded in. I took that a step further and made a function that will tell me if any files were uploaded without having to know the name of the upload field.
/**
* Tests all upload fields to determine whether any files were submitted.
*
* #return boolean
*/
function files_uploaded() {
// bail if there were no upload forms
if(empty($_FILES))
return false;
// check for uploaded files
$files = $_FILES['files']['tmp_name'];
foreach( $files as $field_title => $temp_name ){
if( !empty($temp_name) && is_uploaded_file( $temp_name )){
// found one!
return true;
}
}
// return false if no files were found
return false;
}
You should use $_FILES[$form_name]['error']. It returns UPLOAD_ERR_NO_FILE if no file was uploaded. Full list: PHP: Error Messages Explained
function isUploadOkay($form_name, &$error_message) {
if (!isset($_FILES[$form_name])) {
$error_message = "No file upload with name '$form_name' in form.";
return false;
}
$error = $_FILES[$form_name]['error'];
// List at: http://php.net/manual/en/features.file-upload.errors.php
if ($error != UPLOAD_ERR_OK) {
switch ($error) {
case UPLOAD_ERR_INI_SIZE:
$error_message = 'The uploaded file exceeds the upload_max_filesize directive in php.ini.';
break;
case UPLOAD_ERR_FORM_SIZE:
$error_message = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.';
break;
case UPLOAD_ERR_PARTIAL:
$error_message = 'The uploaded file was only partially uploaded.';
break;
case UPLOAD_ERR_NO_FILE:
$error_message = 'No file was uploaded.';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$error_message = 'Missing a temporary folder.';
break;
case UPLOAD_ERR_CANT_WRITE:
$error_message = 'Failed to write file to disk.';
break;
case UPLOAD_ERR_EXTENSION:
$error_message = 'A PHP extension interrupted the upload.';
break;
default:
$error_message = 'Unknown error';
break;
}
return false;
}
$error_message = null;
return true;
}
<!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
{
$name = $myFile["name"][$i];
echo $name;
echo "<br>";
$temporary_file = $myFile["tmp_name"][$i];
echo $temporary_file;
echo "<br>";
$type = $myFile["type"][$i];
echo $type;
echo "<br>";
$size = $myFile["size"][$i];
echo $size;
echo "<br>";
$target_path = "uploads/$name"; //first make a folder named "uploads" where you will upload files
if(move_uploaded_file($temporary_file,$target_path))
{
echo " uploaded";
echo "<br>";
echo "<br>";
}
else
{
echo "no upload ";
}
}
}
}
?>
</body>
</html>
But be alert. User can upload any type of file and also can hack your server or system by uploading a malicious or php file. In this script there should be some validations. Thank you.
is_uploaded_file() is great to use, specially for checking whether it is an uploaded file or a local file (for security purposes).
However, if you want to check whether the user uploaded a file,
use $_FILES['file']['error'] == UPLOAD_ERR_OK.
See the PHP manual on file upload error messages. If you just want to check for no file, use UPLOAD_ERR_NO_FILE.
I checked your code and think you should try this:
if(!file_exists($_FILES['fileupload']['tmp_name']) || !is_uploaded_file($_FILES['fileupload']['tmp_name']))
{
echo 'No upload';
}
else
echo 'upload';
In general when the user upload the file, the PHP server doen't catch any exception mistake or errors, it means that the file is uploaded successfully.
https://www.php.net/manual/en/reserved.variables.files.php#109648
if ( boolval( $_FILES['image']['error'] === 0 ) ) {
// ...
}