Understanding the Rails Authenticity Token

前端 未结 10 1051
攒了一身酷
攒了一身酷 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: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:

    
    

    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:

    To the harmless survey
    

    Authenticity Token

    When your ApplicationController has this:

    protect_from_forgery with: :exception
    

    This:

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

    Is compiled into this:

    Form contents

    In particular, the following is generated:

    
    

    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.

提交回复
热议问题