1

I have a PHP server that runs a website, and the website has features such as live notifications, which are basically notifications that get sent to you once a user likes or comments on one of your posts, live.

I decided to use WebSocket for this, just for practice. To use WebSocket, I need to authenticate the user and use his information in order to get and deliver data to other connected users.

Stage one

I know that PHP gets the session id of the logged in user from the cookies, and uses that ID to retrieve his session file, which holds his user id.

I thought of saving the session id in a database, linked to the user id, and then when the websocket connection initializes, I send the cookie session id and then the websocket server checks the sent ID from the database.

Stage two

If you like or comment on a post, you need some kind of a service that handles it, whether if you can like or comment, and what it does when you try to do that, and in my opinion that logic should be done on the web server, on the PHP project.

What I thought of doing is first sending an XMLHttpRequest when you like or comment on a post, and that request returns status, if it succeeds or fails. If it succeeds, then the response will contain the ID of the post or like, and it will be sent over to the websocket server, and the server will notify all users after verifying that it's real.

Can you find any flaws in one of these stages? Am I thinking the right way?

  • Not sure.. i believe the websocket call also sends domain cookie information like PHPSESSID within the HTTP header which the Websocket server should be enable to use... So the websocket server should also be able to read the PHP session file (assuming the correct file, user and or group privileges).. Better option whould be to "enable" PHP database session handling so the websocket server can also use the database (safer option) – Raymond Nijland Jul 21 '18 at 11:34
1

[...] if you can like or comment, and what it does when you try to do that, and in my opinion that logic should be done on the web server, on the PHP project.

Oh absolutely. Otherwise you would implement the checks on client side, in which case the web application decides, whether the user is allowed to comment/like a given post. You can do that but implementent server-side checks too! Otherwise nothing prevents me from pretending to be another user and sending the request directly without using your web app. Client-side checks should never be used as the only safety measure.

I'd also implement some sort of one-connection-per-user policy. In case somebody steals/guesses the users session ID, he/she can establish a websocket connection and maybe even use your other endpoints (depending on how they are authenticated). This is a weak spot, as your websocket connection can be established (and other endpoint can be used) by just throwing a valid session ID at your server (regardless of username/password in your scenario!). Make sure sessions time out after X minutes and session IDs are way harder to guess than password (i.e. using a cryptographic hash function or a safe random number generator).

Allowing only one Websocket for each session ID (and only one active session per user?) prevents an attacker from hijacking an actively used session unnoticed.

As usual "don't roll your own crypto" (if you think about using it as production software). As you already mentioned that "PHP gets the user data from the session ID", I assume you're using some sort of framework, as PHP does not do this on its own. Maybe the authentication functionallity is already implemented.

tl;dr

  • Implement all security checks at least on server-side (client-side is User Experience, not security)
  • Make sure that guessing session IDs in not feasible. This includes cleaning up sessions which are no longer in use. Maybe a policy enforcing one session per user and one websocket connection per session if it fits your use case. So nobody can hijack a session unnoticed.
  • "using a cryptographic hash function [for session id]" - Not a great idea generally, it's not specific enough and not really useful anyway. It's only ok to use a hash for session id if the data being hashed has enough entropy, in which case you might as well just use a CSPRNG directly. – AndrolGenhald Jul 20 '18 at 14:11
  • One websocket per user could be problematic for users who like to have multiple tabs open. – AndrolGenhald Jul 20 '18 at 14:13
  • The first part of your answer kinda misunderstands my question for stage two. I never said I will do checks client sided, I said whether if to make it check it on the websocket server, or on the web server. Since most of the logic is handled on the HTTP server, why do it on the websocket server if I only use it as a real-time bridge to my actual application? – Ben Beri Jul 20 '18 at 16:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.