LHall383/hallhome-webapp

Change backend access token key

Opened this issue · 3 comments

Currently the backend uses the code generated by the Spotify request as the key to the access token. This code is long and somewhat annoying to work with. We could instead generate our own string on the backend and return it as the success value from the /auth/submit-code endpoint. This alternative value should just be a random value that doesn't already exist as a key of our dictionary with auth data.

This value could be the SHA3-256 of the code input, perhaps with the client secret or some static, secret salt value appended.

The only issue for this is that we are technically making it easier to brute force into our API.
The current code string is very long ~298 characters, so there are C^298 possible entries (assuming C=26) which is 4.59259e421 possible values
A SHA3-256 hashed value has 2^256 = 1.15792e77 possible values.

So... both approaches are susceptible to brute force exploration of the state space. The probability of selecting one that exists and is valid can be explained by the birthday attack problem (https://en.wikipedia.org/wiki/Birthday_attack). This probability is... very low. To further increase security, we could also rate limit the /auth/is-code-valid/ endpoint which is an external user's primary way to brute force search our keys.

The fastest request I was able to get from our api endpoint was about 5.88 ms with an ethernet connection to the server. Let's play it safe and say we could request and get a valid response in 4ms. That's 250 requests per second, 15,000 per minute, 900,000 per hour, 21,600,000 per day. With a state space of 1.15792e77 it would take a long time (5.36e69 days) to explore the full state space.

But, assuming we have 100,000 users logged in, there is a 100,000/1.15792e77=8.636e-73 probability of picking a valid value for each request sent. So the chance we select an invalid value on each iteration is 1-8.636e-73. (This will of course slightly increase with each guess as there is no replacement, but let's assume it doesn't). This means the chance of stumbling upon a valid value is 1-(1-8.636e-73)^N, where N is the number of guesses. And when I type 1-((1-(8.636*10^(-73)))^21600000) into https://keisan.casio.com/calculator it outputs 1.865e-65. So, after an entire day of trying codes, an attacker has a 1 in a 5.362e64 chance of guessing a valid hash.

So the SHA3-256 approach seems secure.