Iframe causes Can't Verify CSRF Token Authenticity n Rails

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-19 06:21:54

问题


I have a webapp that is loaded through an iframe using phonegap 2.3.0 for Windows Phone 8 SDK. The problem with loading it through the iframe is that it causes Can't verify CSRF token authencity on the Rails side when I send a $.post() request.

I tried a couple of approaches such as overwrite the $.post() to use $.ajax() to setHeaderRequest with the token, and also $.ajaxSetup()

When I disable protect_from_forgery or verify_authenticity_token, the app loads correctly.

I believe the problem is caused because the webapp is located in another domain (cross domain issues) and csrf is simply trying to prevent clickjacking. Is there are way to bypass this problem?

Here is an example of how I am posting:

    $.post(url, {app: {played: tiles}, no: no}, function (response) {
      linkTo('#app_button', response['next']);
    });

Example:

    $.ajaxSetup({
      beforeSend: function(xhr) {
        xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').prop('content'));
      }
    });

Edit: I have been able to pass authenticity token as a parameter into my post request with the same error. I am starting to beleive the error is not cause by the token. What are other reasons why the error occurs?

Log:

[2539 - 2013/03/06 15:37:42] (INFO)   Parameters: {"app"=>{"played"=>"tiles"}, "no"=>"no", "authenticity_token"=>"yBpUImzjtKGIejh/WCekv/GCi1zjPirib22plqfLJ1Y="}
[2539 - 2013/03/06 15:37:42] (WARN) WARNING: Can't verify CSRF token authenticity
[2539 - 2013/03/06 15:37:42] (INFO) User agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)
[2539 - 2013/03/06 15:37:42] (DEBUG)   User Load (1.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
[2539 - 2013/03/06 15:37:42] (DEBUG)   CACHE (0.0ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
[2539 - 2013/03/06 15:37:42] (DEBUG)   CACHE (0.0ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
[2539 - 2013/03/06 15:37:42] (WARN) Lost session [118.143.97.82] (/locations/1/games) - Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)
[2539 - 2013/03/06 15:37:42] (DEBUG)   CACHE (0.0ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1

回答1:


The answer is because of no P3P header which was blocking session storage. You need to add a P3P header to fix this.




回答2:


   <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" >

Add this hidden field to your form. I had fixed the same issue like that of "Can't Verify CSRF Token Authenticity"




回答3:


You can turn CSRF off for certain controller actions. You can make a new action (let's say iframe) for the purpose of the AJAX call and add in the controller:

skip_before_filter :verify_authenticity_token,  :only => [:iframe]



回答4:


The problem is that you need to fetch a new token after an Ajax POST request because once a token is used it gets invalidated. Here is the code to do this:

In rails whenever a POST reply is sent add these parameters to the response:

def someMethod:
    result[:csrfParam] = request_forgery_protection_token
    result[:csrfToken] = form_authenticity_token
    render :json => result
end

Now on the JS side, in the success function of every POST method you can call this function:

var setCsrfToken = function(param, token) {
    if(param == null || token == null) {
        console.error("New CSRF param/token not present");
    }
    $("input[name='" + param + "']").val(token);
}

like this:

setCsrfToken(result["csrfParam"], result["csrfToken"]);

This function will reset all authenticity_token params in all POST forms so that the next request has a valid token. You need to make sure this happens in every POST call, otherwise you'll continue facing this problem.

Also, CSRF is not for preventing clickjacking, it's a separate attack altogether, where another website can make a user click a link that executes an action on your website with the user's session.




回答5:


@user1555300's answer is right just giving the details.

In application_controller.rb add this on top

before_filter :set_p3p

also add this method

private 
# for IE, Facebook, and iframe sessions
def set_p3p
  headers['P3P'] = 'CP="ALL DSP COR CURa ADMa DEVa OUR IND COM NAV"'
end

Make sure this is on the application_controller.rb not a regular controller.



来源:https://stackoverflow.com/questions/15239818/iframe-causes-cant-verify-csrf-token-authenticity-n-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!