Reputation: 2231
in this case I want to safe upload pdf, doc, docx, ppt, pptx, xls, xlsx, rar, zip
prevent from arbitrary file upload especially web shell or any evil script.
The problem is how I can validate file, is safe to upload? prevent from bypass like change mime type with tamper data, rename file with multiple extension, using ;
and space in file name, lowercase and uppercase file extension and etc.
my controller code look like this
public function fileUpload(){
$ext = ['pdf', 'doc', 'ppt', 'xls', 'docx', 'pptx', 'xlsx', 'rar', 'zip'];
$data = Request::all();
$name = $data['file']->getClientOriginalName();
$rules = [
'file' => 'required'
];
$v = Validator::make($data, $rules);
if($v->passes()){
// Check safe file validation
// should here or something? and how to prevent bypass
// arbitrary file upload especially evil script.
$data['file']->move(public_path('assets/uploads'), $name);
return 'file uploaded';
}else{
return 'file upload failed';
}
}
Upvotes: 0
Views: 6707
Reputation: 76
I would suggest looking at Laravel Middleware for the validation. This will reduce the code in your controllers and allow them to be reused.
I personally change the name of any file upload to something random. I can always save the original file name somewhere in the system if needs be.
I would also look at using a htaccess command which prevents file execution from that folder.
Controller method below
Note: it uses App\Http\Requests\CreateUploadRequest;
public function store(CreateUploadRequest $request)
{
$file = Input::file('file');
$destinationPath = 'assets/uploads'; // upload path
$name = $file->getClientOriginalName(); // getting original name
$fileName = time().rand(11111, 99999) . '.' . $extension; // renaming image
$extension = $file->getClientOriginalExtension(); // getting fileextension
$file->save($destinationPath.'/'.$fileName); // uploading file to given path
}
Middleware
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
class CreateUploadRequest extends Request {
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'file' => 'required_if:update,false|mimes:pdf,doc,ppt,xls,docx,pptx,xlsx,rar,zip|max:1000'
];
}
}
I think this idea was taken from a laracast video. I'll have a look around to see if i can find it.
Upvotes: 2