Welcome Guest, Not a member yet? Register   Sign In
form submit with csrf not working
#1

Hi, i have a simple login form which am using to test with csrf. I have enabled CSRFRegenerate to true and also un-commented it in the Filters.php file and also set cookiesecure and cookieHTTPOnly to false. Am testing it on wampserver. When i submit the form; i do not get any feedback from the flash messages have set. It only works when i have excluded the route from the csrf which i do not want to since i plan on using this code in a production site.



PHP Code:
<?php if (session()->getFlashdata('fail')) : ?>
    <div class="alert alert-danger my-1" role="alert">
        <p class="my-1 p-0 text-center">
            <?= session()->getFlashdata('fail'); ?>
        </p>
    </div>
<?php endif; ?>

<form action="<?= base_url().'/login' ?>" method="post" accept-charset="utf-8">

    <?= csrf_field() ?>

    <input type="hidden" value="<?= esc($previousUrl) !== NA_L esc($previousUrl) : base_url();  ?>" id="previous_url" name="previous_url">

    <div class="form-group">
        <label for="loginEmailAddressid" class="_login_label_class">EMAIL ADDRESS</label>
        <input type="email" class="form-control rounded-0 form-control-lg w-100" id="loginEmailAddressid" aria-describedby="emailHelp" placeholder="Email:" maxlength="64" autocomplete="off" name="loginEmailAddress" value="<?= set_value('loginEmailAddress'?>">
    </div>
    <div class="form-group">
        <label for="loginPasswordid" class="_login_label_class">PASSWORD</label>
        <input type="password" class="form-control rounded-0 form-control-lg w-100" id="loginPasswordid" placeholder="Password:" name="loginPassword" autocomplete="off" aria-describedby="passwordHelp">
    </div>

    <br>
    <div class="form-row align-items-center">
        <div class="col-md-6">
            <input type="submit" class="btn-grad btn-grad-2 btn-block" id="loginsubmitbtnid" value="LOGIN">
        </div>
    </div>
</form> 


PHP Code:
// the login route view
$routes->get('login''ExtAccessController::extLogin', ['filter' => 'extnoauth']);
// the route to login
$routes->post('login''ExtAccessController::postExtLogin'); 


In the ExtAccessController; here is the postExtLogin method:

PHP Code:
if ($this->request->getMethod() === 'post') :

    $loginEmailAddress     trim($this->request->getPost('loginEmailAddress'));
    $loginPassword         trim($this->request->getPost('loginPassword'));


    // check validation
    if ($this->validate->run(["loginEmailAddress" => $loginEmailAddress"loginPassword" => $loginPassword], "extLoginValidation")) :

        // session
        $this->userModel->insert([
            "useremail" => $loginEmailAddress,
            "userpassword" => $loginPassword
        
]);

        // set session
        session()->set(['sessionNEextEmail' => $loginEmailAddress]);

        // response
        return redirect()->to('/dash');

    else :

        // error string
        $errStr "";

        if ($this->validate->hasError('loginEmailAddress')) :    $errStr $this->validate->getError('loginEmailAddress');
        else : $errStr $this->validate->getError('loginPassword');
        endif;

        // response
        session()->setFlashdata('fail'$errStr);
        return redirect()->to('/login');

    endif;

else :
    session()->setFlashdata('fail''Unknown error occured');
    return redirect()->to('/login');
endif; 
Reply
#2

(This post was last modified: 11-17-2021, 03:01 AM by captain-sensible. Edit Reason: spelling and extra )

i've got a web dev local and live. On local i like to hit it and see if it shakes. I ran zap against it and it did bring up one or two issues.

I wanted to see if a csrf was being properly sent to a controller.

In my base controller i have :
Code:
public function __construct()
        {
    
        helper(['text', 'date','uri','html','form','security','number']);
                 ..................


As far as i can see when my controller eg Sendmail controller :
Code:
class Sendmail extends BaseController
{

it seems i don't then have to keep declaring helpers in my controller classes


This is how i tested it :



in view :
<?=form_open('contact') ?>

<?= csrf_field() ?>
// here i manually put in csrf to be generated, but i've read if you use appropriate helper and the appropriate form open eg: <?=form_open('contact') ?>

you don't even need to put in the <?= csrf_field() ?> I'm of course a control freak so i like to do things my way.
Now in the bit <?=form_open('contact') ?> 'contact' is in fact a named route; so i am using POST to a ROUTE which passes on to a controller
Class called Sendmail


in my controller

$someVAr= $this->request->getVar(csrf_token());
echo some var


So when i posted form on local , entered text i entered into form text boxes was retrieved and I DID SEE a csrf token being echo'd out. Is that what you want to do , check token is produced and recevied ?
Reply
#3

(11-17-2021, 02:59 AM)captain-sensible Wrote: i've got a web dev local and live. On local i like to hit it  and see if it shakes. I ran zap against it and it did bring up one or two issues.

    I wanted to see if  a csrf was being properly sent to a controller.

      In my base controller i have :
Code:
     
public function __construct()
{

helper(['text', 'date','uri','html','form','security','number']);
                ..................


As far as i can see when my controller eg Sendmail controller :
Code:
class Sendmail extends BaseController
{

it seems i don't then have to keep declaring helpers in my controller classes


This is how i tested it :



        in view :
      <?=form_open('contact') ?>

        <?= csrf_field() ?>
    // here i manually put in csrf to be generated, but i've read if you use appropriate helper  and the appropriate form open eg: <?=form_open('contact') ?>

you don't even need to put in the        <?= csrf_field() ?>    I'm of course a control freak so i like to do things my way.
Now in the bit <?=form_open('contact') ?>    'contact' is in fact a named route; so i am using POST to a ROUTE which passes on to a controller
Class called  Sendmail

   
        in my controller

$someVAr= $this->request->getVar(csrf_token());
        echo some var


      So when i posted form on local , entered text  i entered into form text boxes was retrieved  and I DID SEE a csrf token being echo'd out. Is that what you want to do , check token is produced and recevied ?

Well all i want is to just have my login information sent with the csrf. And since am not using ajax and the page will refresh after submit, display an error or not, the token will be regenerate automatically. Unfortunately am not seeing any feedback unless the form action route is excluded from csrf protection which i don't want to. By the why are you using getVar if its a POST request...what if i used post and returned the error message with the token?
Reply
#4

(This post was last modified: 11-17-2021, 07:25 PM by includebeer.)

(11-16-2021, 10:50 PM)coderscvoen Wrote: When i submit the form; i do not get any feedback from the flash messages have set.

I'm not sure if I understand correctly, but if the CSRF validation fail, it will automatically set an "error" flash message and redirect to the previous page. So your view should echo the error variable if present:
https://codeigniter.com/user_guide/libra...on-failure
Quote:When a request fails the CSRF validation check, it will redirect to the previous page by default, setting an error flash message that you can display to the end user.

(11-17-2021, 02:59 AM)captain-sensible Wrote: <?=form_open('contact') ?>
<?= csrf_field() ?>
// here i manually put in csrf to be generated, but i've read if you use appropriate helper  and the appropriate form open eg: <?=form_open('contact') ?>
you don't even need to put in the        <?= csrf_field() ?>    I'm of course a control freak so i like to do things my way.

You said it yourself, open_form() already add the CSRF field in your form. You don't need to add it again with csrf_field(). Maybe you like to do things your way, but then you'll break your site and waste time trying to understand why it doesn't work. If you don't trust the documentation, you can always look at the code to see what it really do: https://github.com/codeigniter4/CodeIgni...er.php#L62
PHP Code:
// Add CSRF field if enabled, but leave it out for GET requests and requests to external websites
        $before Services::filters()->getFilters()['before'];

        if ((in_array('csrf'$beforetrue) || array_key_exists('csrf'$before)) && strpos($actionbase_url()) !== false && ! stripos($form'method="get"')) {
            $form .= csrf_field($csrfId ?? null);
        

It is always a good idea to study the framework's code. Now you can see what is happening and you can learn some interesting things. Like here, I didn't know it doesn't add the csrf field if it's a GET method instead of a POST!
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
/*** NO support in private message - Use the forum! ***/
Reply
#5

I'm having a similar issue with the CI 4 tutorial. After reading this thread, I removed csrf from $methods in filters.php and now my form submit is working with flashdata being displayed correctly. With csrf in place, form submit does not work, i.e. nothing is submitted and no flashdata is displayed.

I'm a CI newbie so no idea what the issue is ??‍♂️
Reply




Theme © iAndrew 2016 - Forum software by © MyBB