We've got problems

Toshio Kuratomi a.badger at gmail.com
Fri Dec 19 19:40:22 UTC 2008


Toshio Kuratomi wrote:
> Mike McGrath wrote:
>> CSRF:
>>
>> CSRF is a pretty serious deal, toshio is working on it but I'm sure he can
>> use some help.
>>
>> Ticket: #992
>>
> Till brought up concerns with a decrease in usability to do it the way
> I've outlined.  This is certainly a valid problem.  The question is
> whether it outweighs the benefit of mitigating the effects of programmer
>  errors.  Till didn't reply to my last message... though it might be
> that he just decided I was too stubborn to change rather than agreeing
> with me :-).  If anyone sees a way to reconcile both "click from email"
> and "prevent spoofing by default" let me know otherwise I'm committing
> code soon.
> 
I woke up with a possible solution.  Till, Luke, Ricky, and others does
this seem doable?

= Background =

A method in the TG Controller can be marked as needing a non-anonymous
identity like this:

  @identity.require(identity.not_anonymous())
  def foo(self):
    if 'admin' in identity.current.groups:
        # Do admin stuff
    else:
        # Do normal user stuff

The presence of the @identity.require(identity.not_anonymous()) is what
forces the method to redirect to the login page when a user is not
logged in.

If the @identity is not there and the code simply checks inside of the
method, then it usually means the code will do different things if the
user is anonymous or authenticated instead of depending on which group
the user belongs to.

= Addition for CSRF =

The current proposal says that when identity is referenced, we'll check
the CSRF token.  If the token is not present or doesn't match, then
we'll decide the user is anonymous.  If the @identity.require()
decorator is present, we will be checking at that level what the
identity of the user is.

I think it would be possible for us to check whether the user has a CSRF
token at this point.  If not, but the tg-visit session cookie that the
user sent is valid, we can redirect to a page that says "This page helps
prevent CSRF spoofing.  Click to continue to the _requested_resource_."
 The link will go to the original method but will contain the CSRF
token.  So if the user is in control of the browser they can click on
the link and be taken to the resource using their current login session.

= Things this does not do =

* We don't do an automatic redirect here because I think the browser
will process that redirect whether or not javascript is allowed to read
it.  As long as the browser processes the redirect automatically despite
what the same-origin policy says, we've lost the CSRF protection.
(Someone can check whether the 30X status codes and <meta refresh> tags
all do this.)

* If the method in question allows anonymous access then you will get
the anonymous page rather than the CSRF redirection.

  - We might be able to ameliorate this by having the login screen
understand the difference between not having a tg-visit cookie and not
having a CSRF token.  You'd still have to click to login to the page,
(one click to login, the second to return from the CSRF protection) but
the login screen could display the "Please click to continue" instead of
forcing the user to retype their username and password and start a new
session.
  - We might be able to ameliorate this even further if we return enough
information to tell the page that the only reason we aren't logged in is
because of CSRF protection.  With that, the

= Other Notes =

* This would also solve the problem of how to do SSL Client
Authentication.  The SSL Cert alone would take you to the login screen.
 You'd then click on a link (with the CSRF token embedded) to take you
to the screen you want.

* Here's a drawback of putting the CSRF token on GET requests -- When
copy and pasting links, the user's CSRF token would be in the pasted
information.  Having the CSRF token added by javascript when the user
clicks on any link on the page would get around this but requires that
Javascript is enabled in the browser.

-Toshio

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/fedora-infrastructure-list/attachments/20081219/6ca70e51/attachment.sig>


More information about the Fedora-infrastructure-list mailing list