Re: Cross-Site Request Forging (XSRF)
Posted by
Jacques Le Roux on
Mar 05, 2009; 10:30pm
URL: http://ofbiz.116.s1.nabble.com/Cross-Site-Request-Forging-XSRF-tp197647p197654.html
I agree with Adrian. As you well explained David, we can't expect to have a totally secured without paying some price (sometimes too
high) in usability, etc.
So yes +1 for this, I can't see a better way.
Jacques
From: "Adrian Crum" <
[hidden email]>
> David,
>
> Thank you for the thorough explanation of the problem!
>
> From my perspective, any steps taken to improve security are a benefit. At the same time, any steps taken to improve security can
> be thwarted by a skilled hacker.
>
> I think a reasonable approach is to implement measures that improve security without impacting the user experience in a bad way. I
> believe that is the approach you're describing. So, yes - let's go ahead and make some incremental changes.
>
> Let's keep in mind that OFBiz software doesn't stand alone in the effort to prevent attacks - the effort also requires a properly
> configured network and well-trained users.
>
> -Adrian
>
> David E Jones wrote:
>>
>> I've been thinking more about the XSRF problem and what we can do to make OFBiz more secure from this sort of attack. This is
>> related to OFBIZ-1959 and there is more discussion and introduction to it there.
>>
>> The trick is that we want to allow certain things:
>>
>> 1. the client's IP address can change during a session (also an attacker could be behind the same NAT router as the victim)
>> 2. the client may have multiple browser windows or tabs open that are part of the same session
>> 3. the client can jump from any page in an application to any other page in that application
>> 4. once authenticated the client stays authenticated for the remainder of the session (doesn't have to re-auth for each page
>> request)
>>
>> Because of these once a user has authenticated the main secure token they pass around is their session ID. In many cases this
>> session ID is NOT communicated in a secure, ie it is passed over the network in plain text (it is often in the URL, or the user
>> may hit HTTP requests and HTTPS requests). In any case, if an attacker can find the jsessionid then they can forge a request and
>> act like the original user.
>>
>> In reality this is a problem that app servers should take care of, and could take care of in a generic way, but they don't (not
>> any I know of anyway). For example they could do things like using different jsessionid values for secure and non-secure
>> communication (ie different values for HTTPS and HTTP) and only allow the non-secure one (HTTP) to go in the URL.
>>
>> Even with that in place we'd still have to do certain things, but these would be very doable in OFBiz. For example we'd have to
>> make a few small changes so that requests with https=true simply cannot be accessed through HTTP (this is not strictly enforced
>> right now). And even with that they may still be issues, and would certainly be issues for requests that don't use HTTPS.
>>
>> One option is to have the framework generate a random token that is generated for each request so that the next request to the
>> server MUST pass that token otherwise we treat it as if the user is not logged in, and in fact we would just logout the user and
>> make them re-auth. That's an annoyance for the false positive cases, but much more secure.
>>
>> The major false positive case that concerns me related to this is the use of 2 common browser features:
>>
>> 1. the back button: if you go back you'll have a page with an old token in the links and clicking on any link or submitting any
>> form would require you to re-auth
>>
>> 2. multiple windows/tabs: if you begin your session in one tab, then open another page in the same webapp in another tab it will
>> be part of the session; if you then go back to the original tab and click on something the random token will be stale/old and
>> you'll have to re-auth, and that will cause the token to update so when you go back to the second tab and hit any link you'll
>> again have to re-auth
>>
>> The solution of a random token wouldn't be too hard to implement, but this constraint is a real pain. We could restrict this to
>> secure pages only, but basically it means that for those pages users can't use the back button or multiple tabs/windows... and I
>> don't like that one bit!
>>
>> The only solution I can think of to this would basically make the whole thing useless. We could remember past tokens so that as
>> long as you have one of the valid tokens for the session then it's okay. However, if we do that then the random tokens will be no
>> more secure than the jsessionid. We could try harder to keep them more "secret", but if they go into a parameter or even a cookie
>> then they aren't really secure. Maybe we could change all links to form submissions somehow... or maybe not. We'd be back to
>> where intercepting a request that is part of a session could easily reveal the jsessionid AND a random token that would be valid
>> for the rest of that session. Ie, we're back to square one.
>>
>> BTW, even if we go with this, it still isn't perfect. The random tokens would that an attacker would have to watch for responses
>> as all tokens in requests would be invalidated unless they can keep that request from making it to the server (a real
>> man-in-the-middle attack like that is a tough one to handle!). They would have to look at responses to get a token and the
>> jsessionid and then send the forged request before the user hits another page.
>>
>> In other words, for all of this pain, especially not being able to use back or multiple tabs/windows, we effectively shorten the
>> vulnerable time period and restrict the attack methods a bit.
>>
>> ================================
>>
>> One thing that we could do to help with this problem, at least for secure pages, is to tighten things up a bit. I'm thinking of 2
>> things:
>>
>> 1. if a request has https=true then we will not accept http requests AT ALL, we will just return an error message (currently if
>> it is a form submission we just accept it)
>>
>> 2. if a request has https=true we will ONLY pass encrypted data (ie body parameters, not URL parameters) to the service it calls;
>> events may need to be changed to better support this since they have direct access to the request object, but for services we can
>> easily filter this out; that means URL parameters will be ignored in secure requests that call services
>>
>> These things, and perhaps others, would help this problem a lot for secure requests. For non-secure requests... well they aren't
>> very secure anyway! ... and they would continue to be more vulnerable to XSRF attacks too.
>>
>> Anyway, comments and suggestions would be well appreciated...
>>
>> -David
>>
>>
>>
>