Obviously TLS is a must for any and all secure authentication. Please turn your paranoia settings up to 11 for this.
Background: (In case people are unfamiliar with the WebSocket (WS) protocol and its idiosyncrasies) The WebSocket TLS (WSS) connection is a different connection from the HTTP TLS connection. This means that one can not automatically authenticate the other. Because of proxies, especially a malicious one performing a MitM attack, simply having the same remote IP address (or even the same session ID) does not guarantee that the two connections are from the same browser.
WS is a persistent TCP connection with a very limited API on the client side that does not allow inspecting of the TLS details for a WSS connections. It is designed to play well with firewalls and (non-malicious) proxies that restrict traffic to just HTTP traffic, and is desireable due to its ubiquity in modern web browsers.
In PHP, WS is (typically) implemented using a command line (CLI) script, which runs its own server accepting and managing the socket connections directly, rather than being mediated through an HTTP server. (If an HTTP server is involved, it is only to forward traffic after the successful upgrade, and becomes a transparent proxy for all purposes after the handshake.) Thus, the typical PHP superglobals are meaningless in PHP CLI.
Passing cookies is possible during the WS handshake, including a session ID. In PHP CLI it is possible (but ungainly) to access the current session data, even after a state change triggered by the HTTP side of things, if you know the session ID. However, because the cookies are passed only during the WS handshake, the WS server does not get notified of changes to cookies, such as the session ID.
AJAX remains authenticated through the HTTPS connection, of course, and I'm sure there's a way to leverage AJAX requests to authenticate WSS connections using the same browser.
Example Session Hijacking: Alice logs on to bob.com via normal HTTPS means, but happens to have a malicious proxy between them, owned by Mallory, running a MitM eavesdropping attack that has compromised the session ID.
Mallory then uses the session ID in his own session cookie to connect to the WSS server, which is where I run into my issues, because I don't know who to then differentiate between Alice's open and fully-authenticated browser and Mallory's completely different browser on a completely different computer.
So, knowing that the session ID is potentially insecure, is a prime target, and is immutable once the WS connection is initiated, how can I authenticate that a given WSS connection is running in the same browser instance on the same computer as a given HTTPS connection?
Edit: Once the HTTPS connection is started, Mallory does not attempt to interfere in order to prevent being detected. Thus, once TLS is established, the HTTPS connection is secure from Mallory from this point forward, but Mallory would have the session ID still.
Justification for this edge-case requirement: I'm writing open source WebSocket software, thus am unable to enforce protecting the session ID through means such as ensuring the session cookie has the Secure flag set, that the session ID gets regenerated, etc., but can enforce having the implementer include a client script that would aid in ensuring authentication across both mediums.