[
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