[jsr-314-open-mirror] [jsr-314-open] [Spec-869-Specify CSRF Solution] PROPOSAL

Roger Kitain roger.kitain at oracle.com
Fri Oct 1 13:31:38 EDT 2010


  Hey Alexander -

Thanks for the late feedback.
Comments inline..
On 10/1/10 1:22 PM, Alexander Smirnov wrote:
> I disagree with suggested proposal. There are two pitfalls:
> a) additional parameter just increases size of generated html code and
> number of request parameters. JSF forms always contain viewId parameter,
> so adding encoded token to that field will have minimal side effects.
> That token should be checked by StateManager before restoring view.
True - that JSF includes View state that at a bare minimum provides basic
CSRF protection.  It is harder to guess the view state to get into a JSF app
if client side state saving is chosen.  For server side state saving - 
it's a bit easier.
Adding the extra field (which by the way is how Seam does it) enhances 
the protection.

> b) URL parameter does not make sense for forms, but more important for
> 'GET' access. To make this parameter compatible with portal environment,
> it can be passed trough ExternalContext.encodeNamespace method ( while I
> think that it should be portal vendor concern, where secure token has to
> protect whole portal page ).
No - it does not make sense for forms.  This proposal allows various
configuration options.
> c) For token encoded as url parameter this proposal protects whole
> application, so no one can either got logged in to protected site
> because of circular dependencies: to open login page, visitor has to
> have secure token, which one he can get only from JSF login page...
> There should be per-page security configuration.
True, it does.  But we chose this option to have it implicitly done.
> On 09/30/2010 07:59 PM, Roger Kitain wrote:
>>   Folks -
>>
>> I have combined the previous two proposals into one based on valuable
>> feed back from
>> Kito Mann and Neil Griffin:
>>
>> On 9/27/10 5:12 PM, Kito Mann wrote:
>>> On Tue, Sep 21, 2010 at 1:15 PM, Roger Kitain<roger.kitain at oracle.com
>>> <mailto:roger.kitain at oracle.com>>  wrote:
>>>
>>>
>>>      There are two proposals for enhancing CSRF attacks in JSF.  We
>>>      need to pick one.
>>>
>>>
>>> Why? I think it's actually safer to allow both:
>>> http://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet#Disclosure_of_Token_in_URL.
>>> According to this, appending the token works better when you can't
>>> guarantee that a server-side operation is occurring only through POST.
>>> Especially with the new capabilities of JSF 2 for parsing view
>>> parameters, I don't think we can make this guarantee.
>>>
>>> Also, the rewriting approach is what they're using for the generic
>>> filter in Tomcat 7:
>>> http://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet#Disclosure_of_Token_in_URL.
>>> I was talking to Mark Thomas, the guy working on this feature, about
>>> this at JavaOne. As you can see, it doesn't even look like they're
>>> using the hidden field approach (probably because it'd be very hard to
>>> implement in a generic fashion).
>>>
>>>   So, I think we should provide both features, but give the users to
>>> turn off either algorithm, with a context parameter such as:
>>>
>>> javax.faces.CSRF_ALGORITHM=NONE | FORM | URL | BOTH (or ALL)
>>>
>> On 9/21/10 4:20 PM, Neil Griffin wrote:
>>> #1 is probably not compatible with portlets. Portals are in full
>>> control of creation of URLs in general, and it is not possible to
>>> simply append "&javax.faces.Token=XYZ" to a portal's ActionURL and
>>> expect it to work.
>>>
>>> #2 is compatible with portlets, but it would be best to have the
>>> hidden field namespaced. Otherwise it would be like
>>> javax.faces.VIEW_ID which is not namespaced, and can cause problems in
>>> portals.
>>> Neil
>> ==============================================
>>
>> This proposal does the following:
>>
>> - Token is generated on the server consisting (minimally) of a randomly
>>    generated "secret key" (stored in session).  The token can be generated
>>    upon session creation, or, at the time the token hidden field and/or
>>    token Url parameter is produced.
>>
>> - Standard context parameter javax.faces.CSRF_ALGORITHM controls where the
>>    token is produced by the following values:
>>        a. "form" : token is produced as the value of the hidden field with the name
>>           <form client id>:javax.faces.Token  where<form client id>  is the
>>           enclosing form's client identifier (produced with getClientId) - i.e.
>>           the hidden field is namespaced using the form's client identifier.
>>        b. "url" : token is produced and appended as a parameter to the form's
>>           action Url with the same name as in [a].
>>        c. "all" : token is produced as in [a] *and* [b]
>>        d. "none" : no token is produced
>>     The default is [a] "form".
>>
>> - After render time, a subsequent action will send the token to the server.
>> - Restore View Phase processing compares the incoming token request parameter
>>    value with the token value generated from the secret key in the session.
>>
>> Spec Document Modifications:
>>
>> Section 7.5.1:
>>
>> getActionURL:
>>
>> The returned URL must contain the
>> parameter with a name consisting of the form's fully namespaced
>> client identifier, the NamingContainer.SEPARATOR_CHAR and the constant
>> defined by ResponseStateManager.VIEW_TOKEN_PARAM,
>> if the configuration option javax.faces.CSRF_ALGORITHM
>> is set to "url" or "all".  The value of this parameter, known
>> as the "token value" must be a cryptographically produced random generated
>> value (known as the "secret key") retrieved from the session.  If the
>> "secret key" does not already exist in the session, create the random value
>> and store it in the session.  Implementations may choose to produce a more
>> complex token value by combining the random "secret key" with other values.
>>
>>
>> Section 2.2.1
>>
>>   "If the value of the configuration option javax.faces.CSRF_ALGORITHM
>>   is not "none" verify the "javax.faces.Token" request parameter value is
>>   the same as the token value generated from the "secret key" stored in the
>>   session. If the values do not match, throw a meaningful exception.
>>   The exception message must not include the token value."
>>
>> Standard RenderKit Docs
>>
>> - Form Rendering
>>
>> Render a hidden field named javax.faces.Token using the
>> ResponseStateManager.VIEW_TOKEN_PARAM constant if the configuration option
>> javax.faces.CSRF_ALGORITHM is set to the key words "form" or "all".
>> The name must be namespaced with the enclosing form's client identifier.  Render
>> the value of this hidden field, known as the "token value", as a cryptographically
>> produced random generated value (known as the "secret key") retrieved from the
>> session.  If the "secret key" does not already exist in the session, create the random value and
>> store it in the session. Implementations may choose to produce a more complex token value by
>> combining the random "secret key" with other values.
>>
>> Implementation Changes are attached to this issue:
>>
>> [1] https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=869
>>
>>
>> -roger
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> -- 
>> roger.kitain at oracle.com
>> https://twitter.com/rogerk09
>> http://www.java.net/blogs/rogerk
>>


-- 
roger.kitain at oracle.com
https://twitter.com/rogerk09
http://www.java.net/blogs/rogerk




More information about the jsr-314-open-mirror mailing list