Understanding the Rails Authenticity Token

前端 未结 10 1006
攒了一身酷
攒了一身酷 2020-11-22 05:55

I am running into some issues regarding the Authenticity Token in Rails, as I have many times now.

But I really don\'t want to just solve this problem and go on. I w

相关标签:
10条回答
  • 2020-11-22 06:21

    Beware the Authenticity Token mechanism can result in race conditions if you have multiple, concurrent requests from the same client. In this situation your server can generate multiple authenticity tokens when there should only be one, and the client receiving the earlier token in a form will fail on it's next request because the session cookie token has been overwritten. There is a write up on this problem and a not entirely trivial solution here: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/

    0 讨论(0)
  • 2020-11-22 06:23

    The Authenticity Token is rails' method to prevent 'cross-site request forgery (CSRF or XSRF) attacks'.

    To put it simple, it makes sure that the PUT / POST / DELETE (methods that can modify content) requests to your web app are made from the client's browser and not from a third party (an attacker) that has access to a cookie created on the client side.

    0 讨论(0)
  • 2020-11-22 06:24

    Methods Where authenticity_token is required

    authenticity_token is required in case of idempotent methods like post, put and delete, Because Idempotent methods are affecting to data.

    Why It is Required

    It is required to prevent from evil actions. authenticity_token is stored in session, whenever a form is created on web pages for creating or updating to resources then a authenticity token is stored in hidden field and it sent with form on server. Before executing action user sent authenticity_token is cross checked with authenticity_token stored in session. If authenticity_token is same then process is continue otherwise it does not perform actions.

    0 讨论(0)
  • 2020-11-22 06:25

    What is CSRF?

    The Authenticity Token is a countermeasure to Cross-Site Request Forgery (CSRF). What is CSRF, you ask?

    It's a way that an attacker can potentially hijack sessions without even knowing session tokens.

    Scenario:

    • Visit your bank's site, log in.
    • Then visit the attacker's site (e.g. sponsored ad from an untrusted organization).
    • Attacker's page includes form with same fields as the bank's "Transfer Funds" form.
    • Attacker knows your account info, and has pre-filled form fields to transfer money from your account to attacker's account.
    • Attacker's page includes Javascript that submits form to your bank.
    • When form gets submitted, browser includes your cookies for the bank site, including the session token.
    • Bank transfers money to attacker's account.
    • The form can be in an iframe that is invisible, so you never know the attack occurred.
    • This is called Cross-Site Request Forgery (CSRF).

    CSRF solution:

    • Server can mark forms that came from the server itself
    • Every form must contain an additional authentication token as a hidden field.
    • Token must be unpredictable (attacker can't guess it).
    • Server provides valid token in forms in its pages.
    • Server checks token when form posted, rejects forms without proper token.
    • Example token: session identifier encrypted with server secret key.
    • Rails automatically generates such tokens: see the authenticity_token input field in every form.
    0 讨论(0)
  • 2020-11-22 06:30

    The authenticity token is used to prevent Cross-Site Request Forgery attacks (CSRF). To understand the authenticity token, you must first understand CSRF attacks.

    CSRF

    Suppose that you are the author of bank.com. You have a form on your site that is used to transfer money to a different account with a GET request:

    A hacker could just send an HTTP request to the server saying GET /transfer?amount=$1000000&account-to=999999, right?

    Wrong. The hackers attack won't work. The server will basically think?

    Huh? Who is this guy trying to initiate a transfer. It's not the owner of the account, that's for sure.

    How does the server know this? Because there's no session_id cookie authenticating the requester.

    When you sign in with your username and password, the server sets a session_id cookie on your browser. That way, you don't have to authenticate each request with your username and password. When your browser sends the session_id cookie, the server knows:

    Oh, that's John Doe. He signed in successfully 2.5 minutes ago. He's good to go.

    A hacker might think:

    Hmm. A normal HTTP request won't work, but if I could get my hand on that session_id cookie, I'd be golden.

    The users browser has a bunch of cookies set for the bank.com domain. Every time the user makes a request to the bank.com domain, all of the cookies get sent along. Including the session_id cookie.

    So if a hacker could get you to make the GET request that transfers money into his account, he'd be successful. How could he trick you into doing so? With Cross Site Request Forgery.

    It's pretty simply, actually. The hacker could just get you to visit his website. On his website, he could have the following image tag:

    <img src="http://bank.com/transfer?amount=$1000000&account-to=999999">
    

    When the users browser comes across that image tag, it'll be making a GET request to that url. And since the request comes from his browser, it'll send with it all of the cookies associated with bank.com. If the user had recently signed in to bank.com... the session_id cookie will be set, and the server will think that the user meant to transfer $1,000,000 to account 999999!

    Well, just don't visit dangerous sites and you'll be fine.

    That isn't enough. What if someone posts that image to Facebook and it appears on your wall? What if it's injected into a site you're visiting with a XSS attack?

    It's not so bad. Only GET requests are vulnerable.

    Not true. A form that sends a POST request can be dynamically generated. Here's the example from the Rails Guide on Security:

    <a href="http://www.harmless.com/" onclick="
      var f = document.createElement('form');
      f.style.display = 'none';
      this.parentNode.appendChild(f);
      f.method = 'POST';
      f.action = 'http://www.example.com/account/destroy';
      f.submit();
      return false;">To the harmless survey</a>
    

    Authenticity Token

    When your ApplicationController has this:

    protect_from_forgery with: :exception
    

    This:

    <%= form_tag do %>
      Form contents
    <% end %>
    

    Is compiled into this:

    <form accept-charset="UTF-8" action="/" method="post">
      <input name="utf8" type="hidden" value="&#x2713;" />
      <input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
      Form contents
    </form>
    

    In particular, the following is generated:

    <input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
    

    To protect against CSRF attacks, if Rails doesn't see the authenticity token sent along with a request, it won't consider the request safe.

    How is an attacker supposed to know what this token is? A different value is generated randomly each time the form is generated:

    A Cross Site Scripting (XSS) attack - that's how. But that's a different vulnerability for a different day.

    0 讨论(0)
  • 2020-11-22 06:32

    The authenticity token is designed so that you know your form is being submitted from your website. It is generated from the machine on which it runs with a unique identifier that only your machine can know, thus helping prevent cross-site request forgery attacks.

    If you are simply having difficulty with rails denying your AJAX script access, you can use

    <%= form_authenticity_token %>
    

    to generate the correct token when you are creating your form.

    You can read more about it in the documentation.

    0 讨论(0)
提交回复
热议问题