Dan, if you could add the current status of "stateless" view
processing in JSF 2.0 to the CSRF page, we can go from there and draft
some recommendations for users.

I've added a discussion of what JSF 2.0 is doing here:

http://seamframework.org/Documentation/WebVulnerabilitiesAndCountermeasures#H-BuildingTheJSFComponentTreeOnDemand

In client-side state saving, the restore view step is independent of the user's session. All the state necessary to rebuild the view and process the user-initiated event is sent along in the form post. The user could request the form on one day and submit it days later assuming that other session data isn't required (e.g., a login or comment form).

This portability is not present in server-side state saving. The browser merely sends an identifier for looking up the component tree in the session. Without the session, there is no component tree. When that happens, the only reasonable thing for JSF to do is to throw and |ViewExpiredException| or simply render the page again without processing any events.

...that is, until Facelets came along. Facelets offers a "solution" to the stale form problem. By setting the |facelets.BUILD_BEFORE_RESTORE| context-param to true, you can have Facelets reconstruct the component tree in the restore view phase if the one in the session has expired (or the session as a whole expired). This would seem to match the behavior of client-side state saving. It does not. The reason is that the contract of requiring an existing view state to exist is now absent and a postback is no different than a page action. A form on a plain HTML page can now submit a post request directly to a JSF application (you do need an empty |javax.faces.ViewState| hidden field for it to work).

To make things even more troubling, Facelets has become the standard view handler in JSF 2.0 and this behavior of Facelets is now the default. So what do we do?

Well, as it turns out, because of a recent spec change, the "build before restore" feature has been inadvertently disabled in Mojarra, so we may not have to worry about it after all in JSF 2.0. But if it does get "fixed"...
 
Again, there needs to be a token stored in the request when using server-side state saving, similar to how a complex value is stored a hidden form field under client-side state saving. It's okay to have the component tree rebuilt, but only if you are sure that the request is coming from a valid source. One of the prime reasons for not just using client-side state saving is to reduce the amount of data being transferred back and forth between client and server (other reasons are because serialization takes time and destroys object identity).

After adding this section to the page, I noticed that the rest of the page duplicates a lot of what Christian has written on http://www.seamframework.org/Documentation/CrossSiteRequestForgery, so likely some merging and cleanup is in order on my part.

-Dan

--
Dan Allen
Senior Software Engineer, Red Hat | Author of Seam in Action

http://mojavelinux.com
http://mojavelinux.com/seaminaction

NOTE: While I make a strong effort to keep up with my email on a daily
basis, personal or other work matters can sometimes keep me away
from my email. If you contact me, but don't hear back for more than a week,
it is very likely that I am excessively backlogged or the message was
caught in the spam filters.  Please don't hesitate to resend a message if
you feel that it did not reach my attention.