Codeigniter not accepting jQuery POST with CSRF protection enabled - php

I've been trying to POST to a Codeigniter controller (while CSRF protection is enabled) but this keeps failing with HTTP/1.1 500 Internal Server Error and This action is not allowed page.
I tried sending the csrf token along with POST data using the following method (which I found here) but it does not seem to work.
<script type="text/javascript" src="js/libs/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/libs/jquery.cookie.js"></script>
<div id="display">Loading...</div>
<script type="text/javascript">
// this bit needs to be loaded on every page where an ajax POST may happen
$.ajaxSetup({
data: {
csrf_token: $.cookie('csrf_cookie')
}
});
// now you can use plain old POST requests like always
$.post('http://localhost/index.php/handler/test', { name : 'Grim'}, function(data){ $('#display').html(JSON.stringify(data)); });
Here's my Codeigniter config.php file:
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token';
$config['csrf_cookie_name'] = 'csrf_cookie';
$config['csrf_expire'] = 1800;
Here's the controller:
function test()
{
echo json_encode($_POST);
}

add csrf token to data before posting
$.ajax({
type: "POST",
url: url,
data: {'<?php echo $this->security->get_csrf_token_name(); ?>':'<?php echo $this->security->get_csrf_hash(); ?>',/*----your data-----*/}
})
csrf token needs to be send along every request so it needs to be specified by the above echo statements

Related

Codeigniter 3.0 CSRF security on angular js 1.x is getting 500 error on $http.post() method

Codeigniter CSRF security on angularjs 1.x is getting 500 error on $http.post() method . Its worked for me on form submission(ordinary form action submit),but when i use angular ajax for same form submission i am getting 500.Please help me
var angCntrl = angular.module('stepsReg',['ngMaterial', 'ngMessages', 'material.svgAssetsCache','mdPickers','naif.base64','ngFileUpload','uiCropper','ngCookies'])
angCntrl.controller('DemoCtrl', function($scope,$window, $cookies,$http,$mdpDatePicker,$mdpTimePicker,$timeout,$q,$mdDialog,$filter,Upload) {
var cct = $cookies.get('csrf_cookie_name');
$scope.insertid = '';
$scope.outletid = '';
$scope.currentid = currentid;
$scope.stepOneNext = function() {
var insertid = $('#insertid').val();
var profileId = $('.current_id').val();
var pCategory = $('#parentCat').val();
var name = $('#name').val();
var email = $('#email').val();
$http({
method: 'post',
url: base_url+'customer/steponeRegistion',
data:{'csrf_crypt':cct,"insertid":insertid,"profileId":profileId,"pCategory":pCategory,"name":name,"email":email},
config: 'Content-Type: application/json;',
}).then(function (response) {
alert(response.data);
$scope.insertid = response.data;
});
}
CSRF token can be used only once on a page.In Codeigniter 3.0 you can exclude that URL by config file.
$config['csrf_exclude_uris'] = array(); //pass your url in array.
codeigniter will not check any CSRF token.
You need a fresh csrf token if you've already used it once.
You can create a page where you can fetch a new token from.
Use the below functions to get the token name and get a value for it.
$this->security->get_csrf_token_name();
$this->security->get_csrf_hash();
Alternatively, to keep the token the same without regeneration, and to avoid usability concerns, you can turn off csrf regeneration by changing the below config to FALSE. CSRF security is still there, just that you're not required to regenerate its token in each request.
$config['csrf_regenerate'] = FALSE; // in application/config/config.php
https://www.codeigniter.com/user_guide/libraries/security.html#cross-site-request-forgery-csrf

How to make ajax calls in codeigniter HMVC

I am using Codeigniter version 3.0.6 with HMVC Moduler Extension. (MX). When i try to make a ajax call it showing me a error massage 403.
<script>
var site = '<?=site_url()?>';
$('#item-name').keyup(function(){
var d = $('#item-name').val();
$('#item-list').css('display','block');
$.post(site+"/moduleone/lists",{name: d}, function(data, status){
$('#item-list').html(data);
});
});
</script>
After executing this code i get and error in chrome console :
Failed to load resource: the server responded with a status of 403 (Forbidden)
Module Method:
public function lists()
{
echo 'afadfad';
exit();
}
I found the problem. I make codeigniter csrf true. That's why every time i submit a form it need a csrf token. But by the in ajax call there is no csrf token found that why it show the authentication error.
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf';
$config['csrf_cookie_name'] = 'csrf_cookie';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array(
'moduleone/lists'
);
If you turn off (false the csrf_protection) then it work perfect.
if you want more information then check out the codeigniter user_guide.
In order to use base_url() and site_url() you have to load codeigniter url helper.Like this.
$this->load->helper('url');
or you can load it on application/config/autoload.php.Then make your ajax call like this...
<script type="text/javascript">
$(document).ready(function(){
url = '<? echo base_url('moduleone/lists');?>';
$('#item-name').on('keyup',function(){
var d = $('#item-name').val();
$('#item-list').css('display','block');
$.ajax({
type:'POST',
url:url,
data: {name: d},
success:function(data, status){
$('#item-list').html(data);
}
});
});
});
</script>
And in Controller use $this->input->post('name') to get your name sent from ajax call. Like this.
public function lists()
{
$name = $this->input->post('name');// name sent from ajax
echo $name;
}

Ajax with CodeIgniter - data not received on server side

I have the following AJAX:
$.ajax({
type: "POST",
url: base+"tree/plant/",
data:{
name: $('#field_treename').val(),
summary: $('#field_summary').val(),
description: $('#field_description').val(),
address: $('#field_url').val(),
category: $('#field_category').val()
}
})
.done(function(resp){
$('#plant-tree-inner').html(resp);
});
base is my base URL, tree is a controller and plant is a method in that controller.
The URL is correct, the controller and method are in place, with correct names. I've made sure of that by echoing a string in the plant method and it appeared correctly on the client after the AJAX response.
However, none of the post data seems to be arriving at the server.
Doing echo $this->input->post('name'); inside the plant method gives an empty string. Doing var_dump($_POST) gives an empty array. I even tried giving parameters to the plant method but that just throws a missing parameter error.
So where is the data getting lost and why?
EDIT: I see now that my question is wrong. It has nothing to do with CodeIgniter, since the data isn't being sent at all. The field values are undefined according to Javascript, but they certainly exist in HTML:
<input type="text" id="field_treename" placeholder="Tree name" value="" />
Seems like something is wrong with jQuery library.
For test' sake, try to send request avoiding it.
You may try this also..
$.ajax({
type: "POST",
url: base+"tree/plant/",
data:{
name: $('#field_treename').val(),
summary: $('#field_summary').val(),
description: $('#field_description').val(),
address: $('#field_url').val(),
category: $('#field_category').val()
}
success:function(resp){
$('#plant-tree-inner').html(resp);
}
});
Try to simulate the problem in the very basic method like creating another directory in your localhost or server like this and create files as describe below.
in the index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>POST Sending Problem</title>
<script src="jquery-1.12.2.js"></script>
</head>
<body>
Link
<script src="custom_function.js"></script>
</body>
</html>
Create js file for example test.js and put this as test
function test (id, base) {
$.ajax({
type: "POST",
data: {
'id': id
},
url: base,
success: function(data) {
alert(data);
},
error: function(data) {
alert('no data');
}
});
}
Next create a php file your_phpfile.php
<?php
if (isset($_POST['id'])) {
echo $_POST['id'];
} else {
echo "no-result";
}
?>
This would help you determine the problem. If this works fine, try applying it using codeigniter.
Good Luck
User this one..
var request = "name="+$('#field_treename').val()+"&"
request += "summary="+$('#field_summary').val()+"&"
request += "description="+$('#field_description').val()+"&"
request += "address="+$('#field_url').val()+"&"
request += "category="+$('#field_category').val()
and in set as data=request. This should work.

Parameters of ajax request don't change

I' m using cms ModX and want to send Ajax request to server using post method. The problem is that the post data of the second, the third and so one requests doesn't change and remains the same as in the first request.
To clarify the situation I provide the following example.
The javascript is the following:
var reqCount = 0;
$(document).ready(function () {
$(window).scroll(function() {
var dataToPost = {'reqCount' :reqCount};
$.ajax({
url: 'http://example.com/ajaxTest',
method: 'POST',
data: dataToPost,
dataType:"json",
success: function(data){
ajaxCountFromServer = data['ajaxCount'];
reqCount=reqCount+1;
}
});
}
}
Also I created resource with address http://example.com/ajaxTest in Modx with the code, running the snippet:
[[getAJAX]]
getAJAX snippet is the following:
<?php
if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
$reqCount = $_REQUEST['reqCount'];
$json_obj = array("ajaxCount" =>$reqCount);
return json_encode($json_obj);
}
?>
So, after the first scroll reqCount=0, it's passed to server and after the server responses(success callback) ajaxCountFromServer=0 and reqCount=1. There all works well.
However, after the second scroll reqCount=1 and after the server response ajaxCountFromServer=0,but it should be 1.
How to fix it?
The solution is quite simple. In the page customizing of the resource http://example.com/ajaxTest, where snippet getAJAX is called, I just unchecked the checkbox "Cacheable".
The correct way to do it is
[[!getAJAX]]
The snippet is not cached now

403 Forbidden Access to CodeIgniter controller from ajax request

Im having trouble with sending an ajax request to codeigniter controller. It is throwing back a 404 Forbidden Access error. I have found some sort of similar question to this but im not sure if its particular to CodeIgniter framework, and also the solution give in that thread did not solve my problem. below is my ajax request. Im wondering this is probably because of the .htaccess of the root folder of CI Application folder, but i dont want to change its default configuration yet.
Is sending ajax request to CI controller the correct way of implementing this? if not, any suggestion please. Thanks!
var ajax_load = '{loading gif img html}';
var ajax_processor = 'http://localhost/patientcare-v1/application/controller/ajax_processor/save_physical_info';
$("#save").click(function(){
$("#dialog-form").html(ajax_load);
$.post(
ajax_processor,
$("#physical-info").serialize(),
function(responseText){
$("#dialog-form").html(responseText);
},
"json"
);
});
CodeIgniter use csrf_protection, you can use it with Ajax and JQuery simply.
This (ultimate ?) solution work on multiple Ajax request (no 403 ;-) and preserve the security).
Change the configuration
Open the file /application/config/config.php
and change the line $config['csrf_token_name'] by :
$config['csrf_token_name'] = 'token';
You can use another name, but change it everywhere in future steps.
Add CSRF in your Javascript
Add script in a view; for me is in footer.php to display the code in all views.
<script type="text/javascript">
var CFG = {
url: '<?php echo $this->config->item('base_url');?>',
token: '<?php echo $this->security->get_csrf_hash();?>'
};
</script>
This script create an object named CFG. This object can be used in your Javascript code. CFG.url contain the url of your website and CFG.token ... the token.
Automatically renew the CSRF
Add this code in your part $(document).ready(function($){---}) as
$(document).ready(function($){
$.ajaxSetup({data: {token: CFG.token}});
$(document).ajaxSuccess(function(e,x) {
var result = $.parseJSON(x.responseText);
$('input:hidden[name="token"]').val(result.token);
$.ajaxSetup({data: {token: result.token}});
});
});
This script initialize the CSRF token and update it everytime when a request Ajax is sended.
Send the CSRF in PHP
I've created a new controller, named Ajax. In CodeIgniter, the link to use it is http://www.domain.ltd/ajax/foo
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Ajax extends CI_Controller {
public function foo() {
$this->send(array('foo' => 'bar'));
}
private function send($array) {
if (!is_array($array)) return false;
$send = array('token' => $this->security->get_csrf_hash()) + $array;
if (!headers_sent()) {
header('Cache-Control: no-cache, must-revalidate');
header('Expires: ' . date('r'));
header('Content-type: application/json');
}
exit(json_encode($send, JSON_FORCE_OBJECT));
}
}
The send function add the CSRF automatically and transform an array in object.
The final result
Now, you can use Ajax with JQuery very simply !
$.post(CFG.url + 'ajax/foo/', function(data) {
console.log(data)
}, 'json');
Result :
{"token":"8f65cf8e54ae8b71f4dc1f996ed4dc59","foo":"bar"}
When the request get data, the CSRF is automatically updated to the next Ajax request.
Et voilà !
Remove the <code> and application/controller from your ajax_processor like,
var ajax_processor = 'http://localhost/patientcare-v1/index.php/ajax_porcessor/save_physical_info';
If you are hiding index.php from url by using htaccess or routing then try this url,
var ajax_processor = 'http://localhost/patientcare-v1/ajax_porcessor/save_physical_info';
I was facing same problem but now I have fixed this problem.
First of all, I have created csrf_token in header.php for every pages like below code
$csrf = array(
'name' => $this->security->get_csrf_token_name(),
'hash' => $this->security->get_csrf_hash()
);
<script type="text/javascript">
var cct = "<?php echo $csrf ['hash']; ?>";
</script>
After that, when we are sending particular value through ajax then we will have to sent csrf token like below code
$.ajax({
url:"<?php echo APPPATHS.'staff_leave/leaveapproval/getAppliedLeaveDetails'; ?>",
data:{id:id,status:status,'<?php echo $this->security->get_csrf_token_name(); ?>': cct},
method:"post",
dataType:"json",
success:function(response)
{
alert('success');
}
});
I hope this code will help you because this is working for me.
// Select URIs can be whitelisted from csrf protection (for example API
// endpoints expecting externally POSTed content).
// You can add these URIs by editing the
// ‘csrf_exclude_uris’ config parameter:
// config.php
// Below setting will fix 403 forbidden issue permanently
$config['csrf_exclude_uris'] = array(
'admin/users/view/fetch_user', // use ajax URL here
);
$('#zero-config').DataTable({
"processing" : true,
"serverSide" : true,
"order" : [],
"searching" : true,
"ordering": false,
"ajax" : {
url:"<?php echo site_url(); ?>admin/users/view/fetch_user",
type:"POST",
data: {
},
},
});

Categories