Welcome Guest, Not a member yet? Register   Sign In
POST via Ajax returns 403 with CSRF enabled
#1
Sad 

Hello Community,

I've deployed the latest Codeigniter 4.0.2 version and I have an issue when submitting a form with Post method via Ajax when CSRF is enabled, I've tried my best to figure out what is wrong but still no luck.

Notice that:
- When CSRF is disabled, the Ajax call is successful
- If I don't use Ajax and I enable CSRF, the controller handles correctly the request with 200 code

Allow me to share with you the details:

- CSRF enabled globally in the file App\Config\Filters.php:
Code:
// Always applied before every request
public $globals = [
    'before' => [
        //'honeypot'
        'csrf',
    ],
    'after'  => [
        'toolbar',
        //'honeypot'
    ],
];

- CSRF configuration:
Code:
public $CSRFTokenName  = 'csrf_token';
public $CSRFHeaderName = 'X-CSRF-TOKEN';
public $CSRFCookieName = 'csrf_cookie';
public $CSRFExpire    = 1200;
public $CSRFRegenerate = true;  // It fails with false and true
public $CSRFRedirect  = false;

- A simple contact form with the CSRF hidden input created manually:
Code:
<form name='contactForm' class="contactForm" id='contactForm'>
<input type="hidden" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" id="msg_csrf"/>


- When submitting the form, the following Javascript code is being executed:
Code:
const apiUrl = '/api/contact';
const contactCSRF = document.getElementById('msg_csrf');
const contactCSRFName = [contactCSRF.getAttribute('name')];
const contactName = document.getElementById('msg_name');
const contactSubmit = document.getElementById('msg_submit');

contactSubmit.addEventListener("click", function(e){
    e.preventDefault();
    let contactFormData = {
        [ contactCSRFName ] : contactCSRF.value,
        msg_name : contactName.value
    };
    sendContactForm(contactFormData);
});

const sendContactForm = (contactFormData) => {
    $.ajax({
        type: 'POST',
        url: apiUrl,
        data: contactFormData,
        contentType: "application/json",
        headers: {'X-Requested-With': 'XMLHttpRequest'},
        dataType: 'json',
        success: function(result){
            console.log(result);
        },
        error: function(result){
            console.log(result.responseJSON);
        }
    })
}


- When accessing URL /api/contact, the following Controller handles the request:
Code:
<?php namespace App\Controllers;
class Contact extends BaseController
{
    public function index()
    {
        helper(['form', 'validation', 'url']);
        if ($this->request->isAJAX())
        {
            $formDataRaw = $this->request->getRawInput();
            return $this->response->setJSON($formDataRaw);
        } else {
            return '{ \'error\': \'Invalid Request\'}';
        }
    }
}

- Analyzing the Payload, it is correct:
Code:
csrf_token=563def7f2e22a4df1f6e53ce8f0b75d7&msg_name=jdoe

It matches with the cookie:
Code:
Cookie: csrf_cookie=563def7f2e22a4df1f6e53ce8f0b75d7


Mind that I've tried another way to pass the CSRF token, directly to the headers:
Code:
$.ajaxSetup({
    headers: { csrf_token : contactCSRF.value }
})


It is added correctly:
Code:
csrf_token: 563def7f2e22a4df1f6e53ce8f0b75d7


- In all my attempts, the same result, 403 error code:
Code:
code: 403
message: "The action you requested is not allowed."


What am I missing here? CSRF token name and CSRF hash are passed correctly to the controller but it keeps showing 403 error only when the request is performed via Ajax.

Could you please shed some light on this issue?


Thank you in advance for taking your time reading this.
Reply


Messages In This Thread
POST via Ajax returns 403 with CSRF enabled - by marcvidalim - 04-05-2020, 11:39 AM



Theme © iAndrew 2016 - Forum software by © MyBB