Nicolás,

Please don't go into details too much for the example case I came up
with.
I already mentioned in my first post, that if the poll is of any real
concern, it would of course have been put behind a login.
And while we're at it, SSL login, with a 2-tier authenticator device
and iris-scan, just to be sure.
And we need to verify their real ID before allowing signup, because
email-verification is not enough as people can create them on-the-fly.

I realize that protection-by-ip-address is not very safe, but for the
poll example I gave, it might be just enough.
I beg to differ that there are a lot of websites out there using
exactly that.

Working around it is easy, you can use a bunch of proxys, tunnel
request through tor, employ a botnet and probably more.
But by far the easiest (if you own a website) is to just have your
visitors perform the action on your behalf.

So I'm not saying anything about whether or not ip-protected polls are
good or bad practice, I'm just arguing it's a valid use case, which
was protected by default with the old CSRF protection.

Thanks,
Mathijs


On Feb 12, 9:45 am, Nicolás Sanguinetti <h...@nicolassanguinetti.info>
wrote:
> On Sat, Feb 12, 2011 at 6:40 AM, Mathijs <bluescreen...@gmail.com> wrote:
> > On Feb 12, 8:05 am, Michael Koziarski <mich...@koziarski.com> wrote:
> >> CSRF attacks are about using *session* data to perform an action
> >> without the user's knowledge.  The attack you're describing here,
> >> which doesn't rely on session data, could also be performed just using
> >> curl from the command line of the attackers laptop, there's no need to
> >> involve the user's computer at all.
>
> > Except for him not being able to vote twice using curl with the same
> > IP address.
> > The attack allows him to command other people (his visitors) to
> > perform actions on my site.
> > In my opionion, the 'session riding' part of CSRF is not just about
> > the physical session/cookie object, just as much about starting new
> > sessions. (so session as in "the order in which requests are made", we
> > only allow a signup if you first asked for the signup form).
> > But no matter what we think CSRF protection is about, the old behavior
> > was about validating every potentially harmful request, the new one a
> > specific type of attack, which was already covered by the old one.
> > So we can conclude that the security got loosened somewhat (for
> > reasons you mention below).
>
> >> If there's no involvement of the session (or some other
> >> client-browser-specific) vector, then it's not a CSRF attack.
>
> > As mentioned, I think starting a new sessions from a "clean" IP
> > address counts as client-browser specific.
>
> So you're saying people with dynamic IPs which rotate every 12 hours
> (the majority of Uruguay, for example) should just log in into your
> site each time the IP rotates, or am I reading it wrong?
>
>
>
>
>
>
>
>
>
> >> However you're correct that we need a little more documentation than
> >> we had previously because the attack vectors are a touch trickier.  I
> >> intend to post an FAQ blog post and update the guides in a few days to
> >> ensure that it's crystal clear what's required.
>
> > I'm glad we agree documentation is the key.
>
> >> The thing to remember is that we *can't* raise an exception in the
> >> default case any more because *every api request would be rejected*.
> >> For users who don't have any API, then the original behaviour was
> >> probably fine.  However a large portion of rails apps do and we can't
> >> completely break them!
>
> > That's why my API controllers inherit from ApiController instead of
> > ApplicationController, and I don't put the CSRF protection in there.
> > Instead, api calls need an API key param to verify their origin. Also
> > there's "skip_before_filter :verify_authenticity_token" to bypass CSRF
> > protection on a controller or action basis.
> > This is probably what most apps with an API use, because - as you
> > point out - there are already a large number of rails apps out there
> > with an API, working with the old system. So I don't see how they
> > would be broken.
>
> > I agree it's nice we can now configure the behavior ourselves, instead
> > of having to fully bypass it, all I'm saying is that for the default
> > case making sure a request is dropped sounds best to me. The API case
> > should indeed be able to easily switch to other behavior (for certain
> > controllers probably).
>
> >> I see your point and agree that we need a little more documentation
> >> around this.  However it is nowhere near as simple as your suggestions
> >> imply.  Developers will have to understand the implications of their
> >> choices.
>
> > Indeed, of their own choices.
> > But since the default (rails generator) "application" already contains
> > 'protect_from_forgery', which just doesn't do anything unless they
> > start using the session as a security measure, you can't really hold
> > every dev responsible for expecting that they are protected against
> > forged requests from other sites.
>
> >> I suspect we'll end up with an api like:
>
> >> protect_from_forgery :on_failure=>:raise
> >> protect_from_forgery :on_failure=>:reset
> >> protect_from_forgery :on_failure=>:some_method
> >> protect_from_forgery :on_failure=> proc { ... }
>
> > That sounds like a nice api
>
> >> I realise that the previous situation where you could just ignore the
> >> issue was greatly preferable, but that was based on some assumptions
> >> which don't hold.  The old rules don't apply anymore.
>
> > I don't really see why. The old system was easy to bypass for specific
> > controllers and actions, while the default was safe for all abuse-
> > cases. The new system is aimed towards applications with an api that
> > don't want to use skip_before_filter and that do use a session for
> > their security-measures.
> > What assumption does not hold anymore? Which rule changed?
>
> >> > Mathijs
>
> >> > On Feb 11, 9:51 pm, Jon Leighton <j...@jonathanleighton.com> wrote:
> >> >> Hi there,
>
> >> >> As you've identified, the difference between 2.3.10 and 2.3.11, and
> >> >> between 3.0.3 and 3.0.4, in how they handle invalid csrf tokens is that
> >> >> the former will raise ActionController::InvalidAuthenticityToken, but
> >> >> the latter will reset the session.
>
> >> >> What we are trying to protect against is the following situation:
>
> >> >> * Alice is logged in to Facebook
> >> >> * Alice visits badsite.com
> >> >> * Mallory, who owns badsite.com has added some code into the page which
> >> >> makes a request to facebook.com and posts on Alice's wall.
> >> >> * Alice visits badsite.com and without her intending it to be, a comment
> >> >> is posted on her wall
>
> >> >> With the current CSRF protection, the following will happen:
>
> >> >> * Alice is logged in to Facebook
> >> >> * Alice visits badsite.com
> >> >> * Mallory, who owns badsite.com has added some code into the page which
> >> >> makes a request to facebook.com and posts on Alice's wall.
> >> >> * Alice visits badsite.com and without her intending it to be, a request
> >> >> is made to post on her wall
> >> >> * Facebook detects that there is no CSRF token associated with the
> >> >> request, and so logs her out by resetting the session
> >> >> * Then, based on the authorisation rules within the application,
> >> >> Facebook denies to post on the wall, because the user is not logged in
>
> >> >> With the old CSRF protection, the following will happen:
>
> >> >> * Alice is logged in to Facebook
> >> >> * Alice visits badsite.com
> >> >> * Mallory, who owns badsite.com has added some code into the page which
> >> >> makes a request to facebook.com and posts on Alice's wall.
> >> >> * Alice visits badsite.com and without her intending it to be, a request
> >> >> is made to post on her wall
> >> >> * Facebook detects that there is no CSRF token associated with the
> >> >> request and so refuses to serve the request in any way (returns 500)
> >> >> * So nothing gets posted on the wall
>
> >> >> The point is, they are different but both have the effect of preventing
> >> >> the wall post.
>
> >> >> If for some reason you specifically want an exception to be raised in
> >> >> this situation, you can customise handle_unverified_request, but it
> >> >> doesn't compromise the aim of the CSRF protection to no raise an
> >> >> exception, so long as the request is not allowed to go through as
> >> >> authenticated by the existing session.
>
> >> >> Jon
>
> >> >> On Fri, 2011-02-11 at 11:28 -0800, Mathijs wrote:
> >> >> > Hi all,
>
> >> >> > I think CSFR protection broke in rails 2.3.11.
> >> >> > As in: it's turned off now.
>
> >> >> > I tried this in rails 2.3.10 and in 2.3.11 and 2.3.11 seems broken.
>
> >> >> > >rails csrftest
> >> >> > >cd csrftest
> >> >> > >script/generate scaffold post title:string
> >> >> > >rake db:migrate
>
> >> >> > now I visit /posts/new in my browser, use firebug to delete or change
> >> >> > the authenticity token, and submit the form.
>
> >> >> > rails 2.3.11: all fine, new post saved
> >> >> > rails 2.3.10: ActionController::InvalidAuthenticityToken
>
> >> >> > I checked ApplicationController to see if it still contained
> >> >> > "protect_from_forgery", which is the case.
> >> >> > I read the announcement for the csrf changes in 2.3.11 and they talk
> >> >> > about overriding handle_unverified_request for special cases where
> >> >> > there are other ways for authenticating a user. In this simple case I
> >> >> > demonstrated though, there is no concept of a user or logging in (or a
> >> >> > session), so the default action of resetting the session is not very
> >> >> > useful.
> >> >> > In my opinion, CSRF protection is about verifying a request. It
> >> >> > doesn't have anything to do with users/sessions/authentication.
> >> >> > By default, a faulty request (unprotected/wrong token) should not
> >> >> > reach the normal controller action code at all, so the main action to
> >> >> > take when a non-verified request comes in, is to have the
> >> >> > before_filter chain halt. nothing more, nothing less.
> >> >> > Extra stuff (like destroying a session) is up to the user (or nice to
> >> >> > leave in as a default).
> >> >> > So I think the behavior in 2.3.11 is just wrong, because in the
> >> >> > example I gave, the forms just get submitted and stuff gets persisted
> >> >> > to the database.
> >> >> > It's not clear from the announcement at all that you should now make
> >> >> > sure the filter chain halts, or that you must protect your actions by
> >> >> > something that's stored in the session (because that's all that gets
> >> >> > done when a faulty request hits).
>
> >> >> > Maybe I'm just doing something wrong here, please let me know.
> >> >> > Mathijs
>
> >> >> --http://jonathanleighton.com/
>
> >> >>  signature.asc
> >> >> < 1KViewDownload
>
> >> > --
> >> > You received this message because you are subscribed to the Google 
> >> > Groups "Ruby on Rails: Core" group.
> >> > To post to this group, send email to rubyonrails-core@googlegroups.com.
> >> > To unsubscribe from this group, send email to 
> >> > rubyonrails-core+unsubscr...@googlegroups.com.
> >> > For more options, visit this group 
> >> > athttp://groups.google.com/group/rubyonrails-core?hl=en.
>
> >> --
> >> Cheers
>
> >> Koz
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Ruby on Rails:...
>
> read more »

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com.
To unsubscribe from this group, send email to 
rubyonrails-core+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-core?hl=en.

Reply via email to