Studio-42 / elFinder

📁 Open-source file manager for web, written in JavaScript using jQuery and jQuery UI
https://studio-42.github.io/elFinder/
Other
4.64k stars 1.41k forks source link

Passing csrf values in each upload #1328

Closed damascenaluiz closed 8 years ago

damascenaluiz commented 8 years ago

Have a App that generates a CSRF Hash for each POST request. The problem is that I can not pass this value. I used CustomData but this does not pass the values dynamically. I can not upload files and other actions with Elfinder. How to pass data dynamically by the client or the server?

nao-pon commented 8 years ago

@lhpaladin use connector bind & client handlers. Please try it.

connector

function setToken($cmd, &$result, $args, $elfinder) {
    if (isset($result['added']) && $result['added']) {
        $result['csrftoken'] = 'one time token';
    }
}
$opts = array(
    'bind' => array(
        'upload' => 'setToken'
    ),
    'roots'  => array(
        array(
            'driver' => 'LocalFileSystem',
            'path'   => '/path/to/files/',
            'URL'    => 'http://localhost/to/files/'
        )
    )
);

client

var tokenKey = 'token';
var options = {
    url  : 'php/connector.php',
    handlers : {
        upload : function(e, fm) {
            if (e.data && e.data.csrftoken) {
                fm.customData[tokenKey] = e.data.csrftoken;
            }
        }
    }
}
$('#elfinder').elfinder(options);
damascenaluiz commented 8 years ago

@nao-pon I tried the following but it did not work, I'm using CodeIgniter 3.

class Elfinder_lib {

    public function __construct($opts) {
        $opts = array(
            'bind' => array('upload' => 'setToken'),
            'roots' => $opts);
        $connector = new elFinderConnector(new elFinder($opts));
        $connector->run();
    }

    public function setToken($cmd, &$result, $args, $elfinder) {
        if (isset($result['added']) && $result['added']) {
            $token_name = $this->security->get_csrf_token_name(); //return string 'token'
            $hash = $this->security->get_csrf_hash();
            $result[$token_name] = $hash;
        }
    }

}
$(document).ready(function () {
    $('#elfinder').elfinder({
        url: 'arquivos/elfinder',
        lang: 'pt_BR',
        commands: ["home", "up", "back", "download", "getfile", "reload", "upload", "rm", "mkdir", "search"],
        rememberLastDir: false,
        requestType: 'get',
        handlers: {upload: function (e, fm) {
                if (e.data && e.data.token) {
                    fm.customData['token'] = e.data.token;
                }
            }}
    });
})

The function 'setToken' does not seem to be called by the connector. I tried to pass the csrf only by the client using another function with ajax but the upload did not work.

I appreciate the help.

nao-pon commented 8 years ago

@lhpaladin Please check PHP: Callbacks / Callables - Manual.

'bind' => array('upload' => array(array($this, 'setToken'))),
damascenaluiz commented 8 years ago
'bind' => array('upload' => array($this, 'setToken')),

Really now it works. However when it is performed chunk upload (large file) upload does not happen as expected. I'm using CodeIgniter 3 and CSRF protection with token regeneration on every submission, only disabling this feature everything works fine. How to disable chunk upload? Thank you,

nao-pon commented 8 years ago

I added an option uploadMaxConn.

Try uploadMaxConn to 1 of -1

And try edit

public function setToken($cmd, &$result, $args, $elfinder) {
    $token_name = $this->security->get_csrf_token_name(); //return string 'token'
    $hash = $this->security->get_csrf_hash();
    $result[$token_name] = $hash;
}
Shadi-Ayoub commented 6 years ago

I suggest to list the hint below with the topic of integration with CodeIgniter. I struggled for some time till this hint helped me to resolve a similar issue.

image

drajathasan commented 4 years ago

@nao-pon , thanks. It works for me. But just add some script in elfinder init:

fm.customData['<?php echo $csrf['_name'];?>'] = '<?php echo $csrf['_hash'];?>';