0
Today while working on a codeigniter project, I came across the concept CSRF - Cross-site request forgery. This happened when I got error 403 - permission denided when making a GET request in AJAX from VIEW to MODEL.
After investigating the matter, some doubts arose.
- csrf Protection is only used for requests in forms?
- How it works for requests without form submission?
- Where part of the request is hosted the hash-Protection token?
It’s still new to me... But as I noticed, the codeigniter generates through a hash function, a token that prevents the website of the attacker can put the token directly in their claims, this token is accessible in
$this->security->get_csrf_hash();
Now, according to my reading, we will have to use the token in the request, so that it can be compared by the token of the codeigniter. How do we send the token in the request?
[My Code]
[view]
// este request é feito quando desperto um evento choicelist.onchange()
$.ajax({
url: CFG.url + "/application/models/Agenda_model/getAgendaDate",
type: "get", //send it through get method
data: {
date: '02-02-2019'
},
success: function(response) {
console.log(response);
},
error: function(xhr) {
//Do Something to handle error
}
});
// in footer.php, gera o primeiro token
var CFG = {
url: '<?php echo $this->config->item('base_url');?>',
token: '<?php echo $this->security->get_csrf_hash();?>'
};
// after request, guarda token sucessores
$(document).ready(function($){
$.ajaxSetup({data: {token: CFG.token}});
$(document).ajaxSuccess(function(e,x) {
var result = $.parseJSON(x.responseText);
$.ajaxSetup({data: {token: result.token}});
});
});
[Model]
public function getAgendaDate(){
$sql = 'select * from agenda';
$result = $this->db->query($sql);
$send = array('token' => $this->security->get_csrf_hash()) + $result;
if (!headers_sent()) {
header('Cache-Control: no-cache, must-revalidate');
header('Expires: ' . date('r'));
header('Content-type: application/json');
}
// envia o novo token
exit(json_encode($send, JSON_FORCE_OBJECT));
}
I believe my code has a small flaw. However I am receptive to new approach, a new design Pattern. How do I solve error 403?
[config.php]
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'token';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array();
[update] - 06-03-2019
I changed the ajax request from VIEW to Controller. I got the same error:GET http://localhost/Calendar/application/controllers/Basecontroller/getAgendaDate? date=02-02-2019 403 (Forbidden) Then I made another change based on in this documentation on Urls. I changed the URL to http://localhost/name_project/name_controller/method I got the GET error http://localhost/Calendar/basecontroller/getagendadate? date=02-02-2019&token=c058ce37a1246f496be4e8d1937b61b5 404 (Not Found)
[Directory structure]
calendar -
- application
- cache
- config
- controllers
- BaseController.php
- core
- helpers
- hooks
- language
- libraries
- logs
- models
- Agenda_model.php
- third_party
- views
- home.php
- .htaccess
- index
- assets
- system
- .editorconfig
- .gitignore
- composer
- contributing.md
- index.php
[config.php]
$config['base_url'] = 'http://localhost/calendar';
$config['index_page'] = 'index.php';
$config['uri_protocol'] = 'REQUEST_URI';
$config['url_suffix'] = '';
$config['language'] = 'english';
$config['charset'] = 'UTF-8';
$config['enable_hooks'] = FALSE;
$config['subclass_prefix'] = 'MY_';
$config['composer_autoload'] = FALSE;
$config['enable_query_strings'] = FALSE;
$config['controller_trigger'] = 'c';
$config['function_trigger'] = 'm';
$config['directory_trigger'] = 'd';
$config['allow_get_array'] = TRUE;
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'token';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array();
Dude, just an addendum. A View should not communicate directly with the layer Model. In architecture MVC the correct is to use an intermediary for this, ie the Controller.
– pauloimon
If you take a good look you’re exposing the structure of framework and also your Model:
/application/models/Agenda_model/getAgendaDate
.– pauloimon
@Pauloimon thanks for the tip. I’ve noticed this, I came from java, and in java the view gets the model.
– Pedro Correia
Yes, I will use it in Controller. Does it solve error 403?
– Pedro Correia
Right. I believe that’s the reason for the 403 yes.
– pauloimon
@Pauloimon, just one more question. The most appropriate method to access the model loaded in the controller is using a view javascript request for the controller? Or is there another alternative?
– Pedro Correia
Of View to the Controller would have no problem using a request AJAX. The Codeigniter maps access to resources through segments, that is, it would be the equivalent of typing the URL in the browser’s address bar.
– pauloimon
In the CI you should not use the URL directly in that way:
http://localhost/myTasks/application/controllers/BaseController/getAgendaDate?date=02-02-2019
. All access via URL is redirected to the fileindex.php
at the root of the application. The structure of Urls are like that:example.com/class/function/ID
, I mean, it would look something like this in your case:http://localhost/myTasks/basecontroller/getagendadate?date=02-02-2019
.– pauloimon
I tried, I had error 404 page not found. My base url is http://localhost:80/myTasks/application/controllers'
– Pedro Correia
@Pauloimon print_r($this->Uri->segment_array()); returns Array(). There is something?
– Pedro Correia
Try to change yours
$config['base_url']
forhttp://localhost/mytasks
.– pauloimon
I got the error, jquery.min.js:2 GET http://localhost/mytasks/basecontroller/getagendadate? date=02-02-2019 404 (Not Found)
– Pedro Correia
@@Pedrocorreia updates your question, shows how the directory structure and the names of Controllers.
– pauloimon
Let’s go continue this discussion in chat.
– Pedro Correia