The current security model is "Run local events for local people, if there are any troublemakers, give them a slap in person" - this simplifies a lot of things, and works pretty well in practice
~
If we were willing to trade simplicity for security, some notes:
[ ] right now admin-ness is based on the session ID's literal value
we trust the client when the client says "I am an admin"
could have a server-side map of session_id to is_admin, updated on call to login.json
Where would this be stored though? Settings are public, a new database table would be a pain since we want to have as little state as possible
session IDs are public, so maybe a separate cookie which isn't public would be better
rather than a fixed "I am admin" value, have the server calculate some secret value
[ ] admin-ness is global, not per-queue
maybe worth having separate concepts for global admin / per-queue moderator?
[ ] the login process is a fixed "if supplied_password == queue_id: set global admin cookie", so even if we store admin-ness in a secure way, the password for each queue is public
have a per-queue password? Where would that be stored? If it's in the settings, then we need some concept of "private settings" so that users don't see it
store the hash of the password in the settings?
once we have a community API, then username+password combos can be used for logins, and then the queue settings can publicly include moderators: [list, of, usernames]
[ ] session IDs are public, which means people can impersonate each other (delete each other's tracks, use each other's priority tokens, etc)
with admin-ness being based on session ID, this also means that the admin session is public
we could probably have like a random 32-byte session ID, but queue.json only displays the first 8 bytes. Clients can then use the first 8 bytes to figure out "this song probably belongs to me", and the server uses the full session ID for security checks (people could still impersonate each other in public by forging a session ID with the same prefix, but the API wouldn't believe them)
or privately store the session ID, and publicly reveal the hash of the session ID?
[x] Anybody can write anything to the MQTT stream
This isn't permanent damage because the next update from api_queue will overwrite with clean data, but it would be annoying enough to stop an event in progress
Now that no client writes to MQTT, maybe we could lock it down to only accept writes over MQTT-over-TCP (which is only exposed to the inside-docker network) and make MQTT-over-websockets (which is public) read-only?
[ ] CORS is enabled to allow any website to read tracks.json, and localhost to read-and-write to the API
this was an issue when we allowed anybody to read and write to the API, is it still an issue?
perhaps we could limit global-read-and-write to only the "test" queue?
The current security model is "Run local events for local people, if there are any troublemakers, give them a slap in person" - this simplifies a lot of things, and works pretty well in practice
~
If we were willing to trade simplicity for security, some notes:
[ ] right now admin-ness is based on the session ID's literal value
session_id
tois_admin
, updated on call to login.json[ ] admin-ness is global, not per-queue
[ ] the login process is a fixed "if supplied_password == queue_id: set global admin cookie", so even if we store admin-ness in a secure way, the password for each queue is public
moderators: [list, of, usernames]
[ ] session IDs are public, which means people can impersonate each other (delete each other's tracks, use each other's priority tokens, etc)
[x] Anybody can write anything to the MQTT stream
[ ] CORS is enabled to allow any website to read tracks.json, and localhost to read-and-write to the API