Topic: Plupload chunks + Codeigniter + CSRF securty

Hello,

Since is no example like this, I want to share:

The example consists in uploading big files with codeigniter (csrf security active) and plupload chunks.
The problem with uploaded chunks and CSRF is that it is necesary to renew the csrf hash at every chunk upload request.

For codeigniter I created a new library using this code:
https://github.com/moxiecode/plupload-handler-php

In the controller side:

        
//load library
$this->load->library("PluploadHandler");
$this->pluploadhandler->no_cache_headers();
$this->pluploadhandler->cors_headers();
if (!$this->pluploadhandler->handle(array(
    'target_dir' => '/tmp/',
        'allow_extensions' => 'jpg,jpeg,png, zip'
        ))) {
            die(json_encode(array(
            'OK' => 0,
            'error' => array(
            'code' => $this->pluploadhandler->get_error_code(),
            'message' => $this->pluploadhandler->get_error_message()
            )
            )));
        } else {
            die(json_encode(array('OK' => 1, 'next_csrf'=>$this->security->get_csrf_hash())));
}

This is inspired from link above.
So, in the OK response put the csrf hash for the next chunk upload;

In the client side (html, script):

<script>
jQuery(function($) {

    security_csrf = '<?=$this->security->get_csrf_hash()?>';

    var uploader = new plupload.Uploader({
        runtimes : 'html5,flash,silverlight,html4',
        browse_button : 'pickfiles', // you can pass an id...
        multi_selection: false,
        max_file_count: 1,
        container: document.getElementById('container'), // ... or DOM Element itself
        url : 'site_uri/files_upload',
        flash_swf_url : '../js/Moxie.swf',
        silverlight_xap_url : '../js/Moxie.xap',
        chunk_size: '2048kb',
        multipart_params: {
            <?=$this->security->get_csrf_token_name()?> : security_csrf
        },
        filters : {
            max_file_size : '32000mb',
            mime_types: [
            {title : "Image files", extensions : "jpg,gif,png"},
            {title : "Zip files", extensions : "zip"},
            {title : "Movie files", extensions : "mp4,m4v,avi"}
            ]
        },

        init: {
            PostInit: function() {
                document.getElementById('filelist').innerHTML = '';
                document.getElementById('uploadfiles').onclick = function() {
                    uploader.start();
                    return false;
                };
            },

            FilesAdded: function(up, files) {
                plupload.each(files, function(file) {
                    document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
                });
            },
            FilesRemoved: function(up, files) {
            },
            UploadProgress: function(up, file) {
                document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
            },
            ChunkUploaded: function(up, file, result) {
                response_data = JSON.parse(result.response);
                security_csrf = response_data.next_csrf;
                uploader.settings.multipart_params.<?=$this->security->get_csrf_token_name()?>=security_csrf;
            },
            BeforeUpload: function(up, files) {
                //uploader.settings.multipart_params.<?=$this->security->get_csrf_token_name()?>=security_csrf;
            },
            Error: function(up, err) {
                document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
            }
        }
    });

    uploader.init();

});
</script>

After each chunk, change the multipart params with new csrf hash value;

<div id="filelist">Your browser doesn't have Flash, Silverlight or HTML5 support.</div>
<br />
<div id="container">
    <a id="pickfiles" href="javascript:;">[Select files]</a> 
    <a id="uploadfiles" href="javascript:;">[Upload files]</a>
</div>
<br />
<pre id="console"></pre>

Thank you, my first post here.

2 (edited by warlock 2016-04-06 10:53:32)

Re: Plupload chunks + Codeigniter + CSRF securty

The "trick" consists in setting this param:

multipart_params: {
            <?=$this->security->get_csrf_token_name()?> : security_csrf
        },

and keep updating multipart_params (your token name), after each uploaded chunk

ChunkUploaded: function(up, file, result) {
                response_data = JSON.parse(result.response);
                security_csrf = response_data.next_csrf;
                uploader.settings.multipart_params.<?=$this->security->get_csrf_token_name()?>=security_csrf;
            },

"multipart_params" is added to your POST request, on each chunk.