Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Request header does not include HTTP_X_CSRF_TOKEN when using AWS JS SDK

I have a Rails application where I can post answers to questions via ajax, it works fine, however, I have added the aws-js-sdk script to be able to upload images in my answer from the browser, the image will be uploaded to s3 which sends back the url of the newly uploaded image in a callback, then I save the answer.

I included the library like this :

 <%= javascript_include_tag "//sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js" %>

Expected behaviour : when I submit an answer with an image, the request header should include HTTP_X_CSRF_TOKEN to verify the form is submitted from within my website.

Problem : request header does not include HTTP_X_CSRF_TOKEN, which is leading to the error ActionController::InvalidAuthenticityToken

like image 221
Ahmad Al-kheat Avatar asked Sep 05 '16 15:09

Ahmad Al-kheat


1 Answers

The authenticity token is not set in the header. It is set as a hidden field in the form tag, like this:

<form class="edit_user" id="edit_user_6" action="/users/6/set_facilitator" accept-charset="UTF-8" data-remote="true" method="post">
  <input name="utf8" type="hidden" value="✓">
  <input type="hidden" name="_method" value="patch">
  <input type="hidden" name="authenticity_token" value="yrr7gWaLmE8ul4s0JcNmAU6H0YB+c7YR/8yCE7it+cRlG9lfdejTSFT7bhydWEQPSqv2E7gVPQ++9mvfJDfJeA==">
  <select class="form-control" data-submit="true" name="user[facilitator_id]" id="user_facilitator_id">

When you submit the form via AJAX, the authenticity_token is submitted too, as a parameter.

  Parameters: {"utf8"=>"√", "authenticity_token"=>"vcvY+cRQC0oM99l5+BFHu6GShPAedugTP1jRqXCxRa3bVGFLjLSVbMFk78aR5N0ol1WOu1noAo/GF6B67PSk6Q==", ...}

I don't know how the S3 gem works, but if it submits directly to Amazon, then it won't use authenticity tokens. Amazon has no way to know the secret key of your rails app on your server. Show us the HTML code that is generated to see if the S3 gem creates a separate form that is outside of your main form, or if it tries to embed a <form> within another <form>, which is invalid HTML.

If you want, you can turn off token checks in your controller with this line:

protect_from_forgery :except => :action_method

See docs here: http://guides.rubyonrails.org/v5.0/working_with_javascript_in_rails.html#form-for and here http://guides.rubyonrails.org/v5.0/security.html#csrf-countermeasures

like image 135
Chloe Avatar answered Nov 15 '22 13:11

Chloe