alan-mj-lin / Sporeas

TJC projection webapp for service use.
1 stars 0 forks source link

WebSockets Session Hijacking Vulnerability #95

Open eaneatfruit opened 4 years ago

eaneatfruit commented 4 years ago

Description

The Sporeas application currently does not implement any form of session segregation. Once a user enters a room string (such as Toronto), it becomes possible for any user on the public internet to use that room given that they know the URL path. While client-side measures have been implemented to restrict this behaviour, through manual testing, the measures seem inadequate to prevent someone from manipulating an already connected room. This is possibly due to the lack of server-side validation.

Risk

High

Impact

Potential Church Service Disruption

Affected Assets

Evidence

As proof of concept, the below screenshot demonstrates an already connected room. Suppose "East Bay" TJC was using the application for AV purposes.

image

Normally when a user tries to connect to a room where the name is used, the application presents the following error.

image

On a network level, the web socket connection sends a "get state" with the East Bay as the user to check if this has already been taken.

image

The server would respond back with the auth parameter being either True or False. True as in the user-supplied has already been taken, and prevents the user from entering the room with the same name as shown below.

image

This check and prevention can be easily bypassed if an attacker who wishes to manipulate the church service to intercept the server response. The below screenshots demonstrates a proxy application capable of editing requests and responses. Start by sending a websocket connection to connect with the already taken user "East Bay."

image

Even though the room is taken, it is possible to change the auth from True to false.

image

By forwarding this request, now we are able to "hijack" a user's room. By clicking "Project" this second user is now able to perform the actions of the initial connected user.

image

Remediation

It is important to implement server-side checking to ensure server responses are not tampered with. This can be done in a variety of ways. One can implement a session variable, and if the server does not receive the expected parameter, it would drop the request.

hchiam commented 4 years ago

Will need to investigate the python code. I agree with the suggestion: 1) When the 1st user creates East Bay, the server should generate and give the user a unique key. 2) The user then should put that key in sessionStorage or in document.cookie (we'll need to investigate secure implementation) but definitely not in localStorage, in this case. 3) Make the server require a valid key to respond to any form submissions after login.

@eaneatfruit question: sessionStorage or cookies?

hchiam commented 4 years ago

Maybe implement a basic Diffie-Hellman key exchange? https://www.geeksforgeeks.org/implementation-diffie-hellman-algorithm https://www.youtube.com/watch?v=jhXCTbFnK8o (But this still seems vulnerable to man-in-the-middle attacks.)

hchiam commented 4 years ago

It looks like the problem can be simulated by editing the client-side form.js code inside socket.on("auth event", function (msg) { to get inside the condition msg.auth != 'True'

hchiam commented 4 years ago

One can implement a session variable, and if the server does not receive the expected parameter, it would drop the request.

Sure, we could generate a large random number on the client side, but I don't think this prevents man-in-the-middle from circumventing it.

const randomKey = Math.floor((Math.random() * 1000000000) + 9000000000);
socket.emit('user active', {
  user: user,
  randomKey: randomKey
});
sessionStorage.setItem('randomKey', randomKey);