0

I'm so confusing of this forbidden issue. First of all I checked related stackoverflow posts and googled enough but still have no idea.

Project Details:

- Currently used libraries:
    1. Carabiner (https://github.com/bcit-ci/CodeIgniter/wiki)
    2. Template (https://github.com/jenssegers/codeigniter-template-library)
    3. hmvc
    3. instagram_api 

- CSRF Protection turned on (I don't want false the protection)

- Followed main posts
    1. https://stackoverflow.com/questions/40225908/ajax-post-not-working-codeigniter
    2. https://stackoverflow.com/questions/22527412/403-forbidden-access-to-codeigniter-controller-from-ajax-request

- ISSUE: 403 Forbidden ("The action you have requested is not allowed.")

HTML

instagram.php

form_open() function generates hidden field for access token and it is included in ajax posting data.

<input type="hidden" name="csrf_token_localhost" value="3f5887fd41ac4eaa9b558afa7cb4a6de">
...
<?php echo form_open('admin/getInstagramAccessToken', array('id' => 'instagram_settings', 'class' => 'form-horizontal row-border')); ?>
...
    <div class="col-sm-8 col-sm-offset-2">
        <?php  echo form_submit('submit', 'Get my access token', ['class' => 'btn-primary btn btn-get-token']); ?>
    </div>
...
<?php echo form_close(); ?>

Javascript

adminscript.js

$('#instagram_settings').submit(function( event ) {
    var posting_data = $( this ).serializeArray();
    event.preventDefault();
    
    $.ajax({
        type: 'POST',
        dataType: 'json',
        async: true,
        cache: false,
        data: posting_data,
        url: 'admin/getInstagramAccessToken',
        success: function(json) {

            try{
                console.log(json);
            }catch(e) {
                console.log('Exception while request..');
            }

        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log(jqXHR, textStatus, errorThrown);
        },
        complete: function() {
            console.log('ajax complete');
        }
    })

Controller

Admin.php

public function getInstagramAccessToken() 
{
    if ($this->input->is_ajax_request()) 
    {
        $response['status'] = 'success';
        echo json_encode($response);
    }
    else
    {
        // if the request if not ajax then show 404 error page
        show_404();
    }
    
}

When I make the csrf protection status false they all work fine. Or when I changed the post type from "post" to "get". But I want to keep the status true and using "post" method.

Dropbox link for two images:

  1. Hidden csrf token field after form load

  2. Posting Datas

https://www.dropbox.com/sh/e93ubgwzv9zir5j/AAA6vf5IWc1m7rtpGWGCpub4a?dl=0

Community
  • 1
  • 1
brucelin
  • 981
  • 2
  • 11
  • 23

2 Answers2

0

You can by pass this issue by sending the CSRF token with your AJAX request. This is occurring because you have put CSRF protection in 'ON' mode. This can be bypassed only if you sent the request through GET or explicitly put CSRF 'OFF', which of course is not advised.

So the solution is to include the CSRF token in your AJAX requests.

Read this post, to know more about putting CSRF tokens on AJAX requests.

EDIT: Ideally, you shoud send the CSRF token through your data option in ajax requests. Check this link for more info

Penguine
  • 519
  • 6
  • 19
  • The form_open() function automatically adds a hidden field containing the CSRF token to the HTML. – brucelin Nov 25 '17 at 05:12
  • But, as I can see, I could find only the instagram token. You need to accompany the CSRF token separately for each requests – Penguine Nov 25 '17 at 05:15
  • Check this url for two images, one is for hidden csrf field after form load and the other one is for posting datas. https://www.dropbox.com/sh/e93ubgwzv9zir5j/AAA6vf5IWc1m7rtpGWGCpub4a?dl=0 – brucelin Nov 25 '17 at 05:22
  • Plz refresh the page and check whether the token value is changing – Penguine Nov 25 '17 at 05:27
  • sure, $config['csrf_regenerate'] = TRUE; on config.php file – brucelin Nov 25 '17 at 05:29
  • No, please chk the token value on the HTMl page, as sometimes the browser picks the old values from its cache(ignoring the new value sent from the server). Also try to clear the cache once and try sending the request – Penguine Nov 25 '17 at 05:34
0

Please add this snippet in your every form which have type POST.

             <?php  $csrf = array(
            'name' => $this->security->get_csrf_token_name(),
            'hash' => $this->security->get_csrf_hash()
             ); ?>   
              <input type="hidden" name="<?php echo $csrf['name']; ?>" 
              value="<?php echo$csrf['hash']; ?>" />
Waseem Bashir
  • 638
  • 3
  • 10
  • 26