inrupt / websockets-pubsub

WebSockets pubsub for Solid servers
https://github.com/solid/solid-spec/blob/master/api-websockets.md
MIT License
3 stars 0 forks source link

How to authenticate WebSocket connections? #5

Open RubenVerborgh opened 5 years ago

RubenVerborgh commented 5 years ago

Spun off from https://github.com/inrupt/websockets-pubsub/issues/2:

The WebSocket protocol itself does not support authentication (BasicAuth is, effectively, deprecated), and the SOLID spec is silent about both AuthN and AuthZ for WebSockets. One thought I had involved having a client send an auth request before the sub request, applying the same WebACL rules that exist for resource access.

RubenVerborgh commented 5 years ago

Let's have a look at https://www.freecodecamp.org/news/how-to-secure-your-websocket-connections-d0be0996c556/ I like point 4.

Option 1: Auth over HTTP before upgrade

If you’re using websockets for authenticated users, it is a pretty good idea to only allow authenticated users to establish a successful websocket connection. Don’t allow anyone to establish a connection and then wait for them to authenticate over the websocket itself. First of all, establishing a websocket connection is a bit expensive anyway. So you don’t want unauthorized people hopping on your websockets and hogging connections which could be used by other people.

To do this, when you’re establishing a connection on frontend, pass some authentication data to websocket. It could be a header like X-Auth-Token: . By default, cookies would be passed anyway.

Option 2: Auth with command

Like we have pub and sub, we could have auth.

michielbdejong commented 5 years ago

@RubenVerborgh I think your option 1 and your quoted point 4 are the same? So I see you're proposing 3 possible alternatives to my current (planned) implementation with access tickets: http request headers, cookies, and auth command. But each of those was already discussed and discarded in #2, right? To summarise:

acoburn commented 5 years ago

I am not entirely sure that introducing auth would break existing apps. If it is understood that no auth command is the same as "unauthenticated" or public (which is the current situation anyway), then supplying auth would simply be an opt-in mechanism.

RubenVerborgh commented 5 years ago

@RubenVerborgh I think your option 1 and your quoted point 4 are the same?

They are.

But each of those was already discussedand discarded in #2, right?

Hmm yeah, we really need topic-specific threads. "Implementation questions" is too generic of a thread to follow.

I really think there has not been enough discussion about this topic, and it doesn't help that it was (not purposely) hidden in another thread.

  • http request headers -> not ideal, because when you call new WebSocket(...) in JavaScript in the browser, you have no way of setting custom http headers

Agreed, this is a major blocker.

  • cookies -> not ideal, because cookies on an API are generally a bad idea

Well, no solutions are ideal, it's always a trade-off.

If Cookie is the only header we can set, and headers are deemed an interesting mechanism, we could still go for it. For instance, we can say that the API uses the Authorization header by default (for non-browser scenarios); if unavailable, then it becomes Cookie.

  • auth command -> not ideal, because it would break existing apps

I don't consider this a sufficient argument, because every possible solution we can pick at this point breaks existing apps. It used to be unauthorized, now it is; that simple fact breaks things. Happy to provide examples when in doubt.

  • access tickets -> the one I chose. It does raise valid security considerations, but these can be mitigated, and are probably not as bad as they seem, especially because we require TLS

We need much, much more discussion. This is a medium spec change, not something small.

RubenVerborgh commented 5 years ago

"unauthenticated" or public (which is the current situation anyway)

Unfortunately, "God mode" is the default.