Dark Cyber
Dark Cyber

Reputation: 2231

Laravel 5 safe upload document files

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

Answers (1)

Darren
Darren

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

Related Questions