CodeIgniter Forums

Full Version: CSRF The action you have requested is not allowed
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I know this has been asked a bit but can not find suitable solution.

When I submit form and if there is a error and then reload page it shows


Quote:The action you have requested is not allowed.

I am not sure why I am using the form helper on my login. It only seems to be if I submit form and error and then reload page / F5 it will show up bit strange? Any ideas what else to do?

If it matters I am on local host and my url is http://localhost/qna/


PHP Code:
<div class="page-wrapper">
<
div class="container">
    <
div class="row" id="login-row">
        <
div class="col-lg-6 col-lg-offset-3">
        <?
php echo form_open_multipart('admin/login', array('id' => 'form-login''class' => 'form-horizontal'));?>        
        <div class="panel panel-default">

        <div class="panel-heading">
        <h1 class="panel-title">Login</h1>
        </div>

        <div class="panel-body">

        <?php echo validation_errors('<div class="alert alert-warning">''</div>');?>

        <div class="form-group">

        <?php 

        $data 
= array(
            
'class' => 'col-lg-2 col-md-2 col-sm-2 hidden-xs'
        
);

        echo 
form_label('Username''username'$data);

        
?>

        <div class="col-lg-10 col-md-10 col-sm-12 col-xs-12">

        <?php 

        $data 
= array(
     
       'name' => 'username',
     
       'id' => 'username',
     
       'class' => 'form-control',
     
       'value' => set_value('username'),
     
       'size' => '50',
        );

        echo 
form_input($data);

        
?>

        </div>

        </div><!-- Form Group -->

        <div class="form-group">

        <?php 

        $data 
= array(
            
'class' => 'col-lg-2 col-md-2 col-sm-2 hidden-xs'
        
);

        echo 
form_label('Password''password'$data);

        
?>

        <div class="col-lg-10 col-md-10 col-sm-12 col-xs-12">

        <?php 

        $data 
= array(
     
       'name' => 'password',
     
       'id' => 'password',
     
       'class' => 'form-control',
     
       'value' => set_value('password'),
     
       'size' => '50',
        );

        echo 
form_password($data);

        
?>

        </div>

        </div><!-- Form Group -->

        </div><!-- Panel Body -->

        <div class="panel-footer">
            <?php 

            $data 
= array(
                
'type' => 'submit',
         
       'id' => 'submit',
         
       'class' => 'btn btn-ci btn-block'
            
);

            echo 
form_button($data'Login');

            
?>
        </div>

        </div><!-- Panel -->
        <?php echo form_close();?>
        </div>
    </div>
</div>
<div class="push"></div>
</div> 


PHP Code:
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'token';
$config['csrf_cookie_name'] = 'cookie';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array(); 
Can you show the controller that is doing the validation check and reloading the page.
(09-24-2016, 03:50 PM)PaulD Wrote: [ -> ]Can you show the controller that is doing the validation check and reloading the page.

PHP Code:
<?php

defined
('BASEPATH') OR exit('No direct script access allowed');

class 
Login extends MY_Controller {

    public function 
__construct() {
        
parent::__construct();
        
$this->load->library('form_validation');
    }

    public function 
index()
    {
        
$data['title'] = __CLASS__;

        
$this->form_validation->set_rules('username''username''trim|required');
        
$this->form_validation->set_rules('password''password''trim|required|password_verify');

        if (
$this->form_validation->run() == true) {
            
$this->session->set_userdata(array('user_id' => $this->getUserID()));
            
redirect('admin/dashboard');
        }

        
$data['content'] = 'account/login_view';

        
$this->load->view('admin/template/common/template'$data);
    }

    public function 
getUserID(){
        
// This is a custom function on forum validation
        
if ($this->form_validation->password_verify() == true) {

            
$this->db->where('username'$this->input->post('username'));
            
$query $this->db->get('user');

            return 
$query->row()->user_id;

        }
    }

MY_Forum_validation

PHP Code:
<?php

class MY_Form_validation extends CI_Form_validation {

    public function 
__construct() {
        
parent::__construct();
        
$this->CI =& get_instance();
    }

    public function 
password_verify() {
        
$hash $this->get_password();
        
$password $this->CI->input->post('password'true);

        if (
password_verify($password$hash)) {
            return 
true;
        } else {
            
$this->set_message('password_verify''Incorrect login information!');
            return 
false;
        }

    }

    public function 
get_password() {
        return 
$this->CI->db->get_where('user', array('username' => $this->CI->input->post('username'true)))->row()->password;
    }

Quote:I know this has been asked a bit but can not find suitable solution.

When I submit form and if there is a error and then reload page it shows

So is this what is happening?

1. Page loads
2. Form submitted
3. Page loads with error messages
4. You manually press 'reload page'
5. Get CSRF error

If so, then yes, this is what it should be doing.

1. Page loads (CSRF set to 'abc...')
2. Form submitted (CSRF checked, passes, reset to 'xyz...')
3. Page loads with error messages (Plus new CSRF code 'xyz...')
4. You manually press 'reload page' (Tries to reload the original post with 'abc' code)
5. Get CSRF error (CSRF checked, fails as sending 'abc...' but expecting 'xyz...')

The only way to alter this behavior is to not reset the CSRF code automatically, which I do not recommend doing. What you are trying to overcome is exactly what CSRF is there to prevent, posting of form data that was either already posted or did not originate from the server.

Sorry if that is not much help. What would represent a 'suitable solution' for you, how would you want it to behave?

Paul.
I know about CSFR protection and I'm very happy that codeIgniter gives us this security mechanism.
But I still wonder what is the best way to handle this error?

You have to account for users that try to resubmit a form. Letting them run against this error wall is probably the worst experience for the user.

Instead there should be an appropriate error-page telling the user that the form was already submitted. but since this error is not a server error you can't catch it with an error controller or via routing (like for ex. a 404 page). or can you?

so how do you handle this? whats the best practice with codeIgniter?
How could I manage to get the error message posted within the regular error messages returned with the form, instead of having this ugly(!) default page error?


(09-25-2016, 10:07 AM)PaulD Wrote: [ -> ]
Quote:I know this has been asked a bit but can not find suitable solution.

When I submit form and if there is a error and then reload page it shows

So is this what is happening?

1. Page loads
2. Form submitted
3. Page loads with error messages
4. You manually press 'reload page'
5. Get CSRF error

If so, then yes, this is what it should be doing.

1. Page loads (CSRF set to 'abc...')
2. Form submitted (CSRF checked, passes, reset to 'xyz...')
3. Page loads with error messages (Plus new CSRF code 'xyz...')
4. You manually press 'reload page' (Tries to reload the original post with 'abc' code)
5. Get CSRF error (CSRF checked, fails as sending 'abc...' but expecting 'xyz...')

The only way to alter this behavior is to not reset the CSRF code automatically, which I do not recommend doing. What you are trying to overcome is exactly what CSRF is there to prevent, posting of form data that was either already posted or did not originate from the server.

Sorry if that is not much help. What would represent a 'suitable solution' for you, how would you want it to behave?

Paul.
(11-20-2017, 01:46 AM)blaasvaer Wrote: [ -> ]How could I manage to get the error message posted within the regular error messages returned with the form, instead of having this ugly(!) default page error?

You will have to extend the core class CI_Security and override the method csrf_show_error()

But the point of CSRF is deflecting cross-site scripting attacks and returning a helpful message to the hacker may not be the best idea.