[ 
http://www.stripesframework.org/jira/browse/STS-363?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11663#action_11663
 ] 

Andrew Jaquith commented on STS-363:
------------------------------------

The approach for frustrating XSRF attacks (aka CRSF) I've seen is similar to 
what you've described here: generate a "transaction token" (nonce); embed it 
into a form returned by the display JSP (obtained by the initial GET); stash a 
copy of the token in the HttpSession; then, when the POST is processed, compare 
the submitted nonce with the stashed copy.

I've been thinking about this issue in relation to solving a particular 
spam-bot problem we have with JSPWiki, the display tier of which is being 
migrated to Stripes. Like you, I'd like to solve this in a Stripes-friendly 
way. There are two issues that need solving: (1) generating and returning the 
token (I prefer the word "ticket" here) to the user, and (2) processing the 
submitted ticket. And of course, it needs to be done in a simple and elegant 
way that is appropriate for Stripes.

I think I have an idea on how to do this. Here's the approach.

First, there's the issue of the ticket. As for (1), this could be done two 
ways. 

a. The Stripes FormTag could be extended to write the ticket name and value out 
as a hidden field, similar to how the source page is written out today when 
someone uses the stripes:form tag, or....

b. The ticket could be written out as a cookie with a unique name, and value 
equal to the ticket value. (It should be possible for the user to have multiple 
'transactions' going at once). 

In both cases, the ticket name and value would be stashed in the HttpSession. 
The processing step at time of POST processing (2) would involve checking for 
the correct value, and if found, removing it from the list of stashed tickets. 
Failure to find the ticket would cause a checked Exception to be thrown, which 
could be picked up by an exception handler.

I haven't seen the cookie option discussed in the security community before, so 
I'm going to solicit some opinions from some security researchers about the 
viability of this approach. The advantage of using cookies is that no 
form-rewriting is needed, so you wouldn't need to modify the Stripes FormTag. 
It's also more "portable" in the sense that it doesn't require developers to 
use Stripes form tags The disadvantage is that the ticket doesn't travel with 
the form. I am not sure how big a deal this is, though, because the point of 
the ticket is that *you must have one* and *it expires*. 

Now, here's how to wrap everything up with some nice Stripes-like simplicity: 
use annotations to simply indicate which event methods require tickets. Here's 
the idea:

@PredecessorEvent(beanclass="com.example.MyActionBean" event="bar")
@HandlesEvent("foo")
public Resolution foo() { ...}

The PredecessorEvent annotation indicates that event handler method "foo" 
requires the event handler method "bar" of MyActionBean to have previously 
executed before method "foo" can run. We assume that method foo() forwards to a 
display JSP that contains the form, though it need not. We can guarantee that 
"bar" runs before "foo" by using our CRSF tickets. Simple introspection at 
startup time would determine that there is a predecessor/successor relationship 
between method "bar" and method "foo," so when "bar" runs we know we need to 
inject a CRSF ticket.

What would make this all work is a "TransactionInterceptor" that injects the 
initial ticket for the first method (the GET of the display JSP), and inspects 
the ticket needed to the execute second method (the POST).

A nice side benefit to this approach is the ability to enforce specific paths 
through the webapp (you could chain @PredecessorEvent annotations across 
multiple ActionBeans).

I'd like to get some comments from the Stripes committers about this. I'm happy 
to work something up as a proof of concept if the approach seems viable.

> Flow Control Token to prevent XSRF/double-posting
> -------------------------------------------------
>
>                 Key: STS-363
>                 URL: http://www.stripesframework.org/jira/browse/STS-363
>             Project: Stripes
>          Issue Type: New Feature
>          Components: Context Management, Tag Library
>            Reporter: Sylvan von Stuppe
>            Priority: Minor
>
> I would love to have a built-in feature for generating a random token, 
> putting this token into the user's session, then be able to have the same 
> token as a hidden form value on subsequent pages.  When a user submits a 
> page, the token the send is checked against the one in the session (possibly 
> as part of the @Validate annotation?) and if they don't match, the user is 
> sent to a different page.  If they do match, the action continues.
> I attempted to do this as part of a BaseActionBean class, but it quickly fell 
> apart because the default binding is for the form to be populated by what the 
> user submitted, not what's in the bean.  So the first request would work 
> because the user didn't submit anything, the attribute is gotten from the 
> bean (which would generate the new token, set it in the session, and return 
> it), and was presented on the form.  But on subsequent requests, the value 
> came from what the user submitted (the old token), rather than from the bean. 
>  So I ended up having to use a vanilla <input> tag with ${} to get the value 
> out of the request scope.
> I don't know of the most "Stripes friendly" way to implement this, but I 
> suspect it would require changes to the ActionBeanContext and certainly the 
> tag libraries.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://www.stripesframework.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to