you are viewing a single comment's thread.

view the rest of the comments →

[–]fschmidt 10 insightful - 5 fun10 insightful - 4 fun11 insightful - 5 fun -  (11 children)

If only they didn't suck. I explained here why they suck:

BitChute sucks because its core function, video streaming, sucks. Videos often stall or don't play at all. And BitChute's search sucks. BitChute is a technical failure. Rumble sucks because their feed/subscriptions page isn't sorted by date. Here we see typical modern tech thinking. Some techno-scum at Rumble thought up some pointless innovation for sorting that actually ruins the site and makes it totally useless. And finally Odysee sucks because they require a password so complex to sign up that I couldn't produce one. This reflects modern techno-scum's obsession with security in places where security doesn't matter at all. Modern techno-scum, even on the right, hate individual freedom, so they refuse to give users the freedom to choose their own password. And of course they can't be bothered with making things easier for users by, for example, generating a password for the user. Since Odysee obviously hates the end user, I won't use Odysee.

[–]Chipit 11 insightful - 4 fun11 insightful - 3 fun12 insightful - 4 fun -  (10 children)

Really went off the rails with that last point against Odysee. You also contradict yourself.

Your password manager should have a "generate password" option, which gives you a 16 digit password full of all the symbols, capital letters, and digits you need. And if you don't have a password manager? Well sheesh you should really have one.

[–]fschmidt 7 insightful - 4 fun7 insightful - 3 fun8 insightful - 4 fun -  (9 children)

Why should I have a password manager when Chrome already remembers my passwords? All the scum running Odysee would have to do is generate a password for me.

Actually the whole idea of passwords is retarded. On my sites one just enters one's email and gets a link with a hash that sets a persistent cookie. No need for annoying passwords.

[–]L_X_A 5 insightful - 4 fun5 insightful - 3 fun6 insightful - 4 fun -  (8 children)

On my sites one just enters one's email and gets a link with a hash that sets a persistent cookie. No need for annoying passwords.

That's a cool concept.

If I understood you correctly:

  1. The user first enters his email address on your site to login/register.
  2. Your server then generates a nonce (say, 128-bit, Base64 encoded) and associates it with that email address.
  3. The nonce is then sent to the user's email as the parameter of a hyperlinked URL (e.g. fschmidt.cool.site/authn/ZnNjaG1pZHQncyBzaXRl)
  4. Your server checks the nonce for a) an associated email, and b) the time elapsed since generating the nonce and the endpoint call (say, less than 10mins)
  5. If all checks pass, you produce a long(er) lived cookie to be used as a bearer token by the user agent (browser, app, etc.)

Which means that the user's email service is the de-facto (albeit indirect) authentication provider.

Cookies should not be valid indeterminately. You'd just be spreading that attack vector wide open. With that in mind, how would you deal with a user who has been inactive past the cookie's expiration date? Do you just send them a new URL containing a new nonce? How do you prevent an attack where nonces are requested repeatedly? Heuristically through API management or do you simply cap-and-throttle?

[–]fschmidt 5 insightful - 4 fun5 insightful - 3 fun6 insightful - 4 fun -  (5 children)

My server generates a crypto hash (MD5 for now) of concat(email,secret_salt) and sends that in the URL to the user's email. That link then sets 2 persistent cookies, the user's email and the hash. So the server doesn't need to store anything and can verify the cookies. On a HTTPS site there is no way for this to be broken, so I see no problem with making the cookies persistent. What problem do you see? The only possible leak is the email itself, but that problem applies to all password systems anyway.

[–]L_X_A 5 insightful - 3 fun5 insightful - 2 fun6 insightful - 3 fun -  (4 children)

The problem with perennial cookies are multiple. From the top of my head, the main ones relate to either someone stealing the cookie on the client (e.g. through javascript if you don't set the HTTPOnly flag), or the user logging in from a machine someone else has access to (e.g. library), or the user trying to connect to your site from a public network (hotel, Starbucks, etc.) and falling victim to an MiTM attack (no, HTTPS would not help you in this scenario. Unless your are using mTLS you wouldn't know whether you are talking to the MiTM or the legitimate user).

Also, depending on how you configured SSL, there are ways to downgrade it client-side so the attacker could sniff the communication even if they're not directly relaying information to and from the legitimate user.
Examples: https://access.redhat.com/articles/1232123 and https://freakattack.com/

But I think the perennial cookies are the least of our problems here.

I'm assuming that:

a) site_password is a static secret in your server which is used of all users. That is, user_1 gets MD5(concat(email_1, site_password)); user_2 gets MD5(concat(email_2, site_password)) and so on.

b) The cookies themselves are not encrypted.

If that's the case, with this simple attack I could impersonate all of your users:

  1. Register for your site with my email 1337.h4x0r@veryedgy.com
  2. receive MD5(concat(1337.h4x0r@veryedgy.com, site_password)) = myEmailDigest
  3. Run a parallelized MD5 crack, varying variable_salt on concat(1337.h4x0r@veryedgy.com, variable_salt)until I get myEmailDigest (with MD5 there are optimized ways of doing this).
  4. Now I know which variable_salt value will produce an MD5 hash which will be interpreted as legitimate by your server. Even worse, I potentially stumbled upon site_password itself. All I need now is a few more fake accounts and MD5(concat(fakeEmail, site_password)) results to be 99% sure.

From this point on, I have deduced site_password and thus have access to all of your users' accounts because all of them are authenticated through site_password.

I mean, it's good enough for a school/uni project. Or a site where it doesn't matter if one user can impersonate another (e.g. those "scrum poker" sites that don't require an account). But I wouldn't put it on anything which has persistent user data. Especially if it is used by people living in a country where GDPR applies.

[–]fschmidt 5 insightful - 3 fun5 insightful - 2 fun6 insightful - 3 fun -  (3 children)

These are valid issues. The javascript and MiTM attack issues are the least serious since they only risk exposing individual users. I don't see any solution for this with any system. A nonce just limits the time of exposure, nothing more. My sysadmin configured SSL and I assume he did it right. I have thought about the last issue you mentioned. I don't care for now while the sites are small and no one will bother. Later I would generate user passwords and store them in the user record and use that instead of a global salt, which solves this issue. If these things are addressed, I can still use persistent cookies. But I will worry about these issues in proportion to the size of the sites (number of users). In general, I don't have any site where security is really critical like a banking site would be. I don't keep credit card numbers or anything like that.

[–]JasonCarswell 1 insightful - 2 fun1 insightful - 1 fun2 insightful - 2 fun -  (2 children)

Can you add a little extra salt to make it seem a little more randomized? ie. Multiply the password by the/a time/date stamp or some other changing variable (title of current top thread title of FreedIt)?

cc /u/L_X_A

[–]fschmidt 2 insightful - 2 fun2 insightful - 1 fun3 insightful - 2 fun -  (1 child)

I thought more about this. What I will do is to generate a new password every time a user logs in. I will store that password in the database and include that password in the emailed URL. So no crypto or hash needed. And this completely eliminates the last problem that /u/L_X_A mentioned.

[–]L_X_A 2 insightful - 2 fun2 insightful - 1 fun3 insightful - 2 fun -  (0 children)

If you want to prevent the attack I described and still not have to store the passwords/salt-values in your server, you could go the authentication through encryption route.

Namely, you'd ditch the email and hash cookies for a single cookie containing the user's encrypted email address.

  • When the user registers with user_email, you send them an URL that will result in them receiving the cookie user-cookie = Encrypt(user_email, server_secret).
    I'd recommend a symmetric, strong (enough) cipher such as AES-256-GCM or ChaCha20Poly1305. You did choose MD5 as hashing algo earlier, and I'm assuming you did so for performance reasons. So it's up to you to judge which cipher would still accommodate your performance needs.

  • Don't forget to set the HttpOnly, Secure and SameSite flags.

  • On every request, the server would decrypt the ciphertext in the user-cookie's value using Decrypt(ciphertext, server_secret). If it matches the email of a user account, the authentication succeeded. Here's where you should watch out for your performance needs. This needs to be done on every request.

This solves the following problems:

  • You are no longer storing (plaintext) user information in the cookie, thus compliant with GDPR (see: https://www.gdpreu.org/the-regulation/key-concepts/personal-data/)

  • If someone steals the cookie, they won't be able to know what's in there.

  • If you chose a decent cypher, a plaintext collision attack as I described earlier becomes unfeasible.

This method still has the problem that every user's email is encrypted with the same key, though. So should someone be able to crack server_secret (very difficult depending on the cipher you choose, but still), they would be able to access every account they know the email of.

To circumvent this, you could extend this pattern with a Diffie-Hellman-based KDF functionality:

  • On your server, instead of the symmetric key as stated above, you generate and store a secret prime number which will be used in a "deferred" Diffie-Hellman key agreement. That is: server_secretPrime

  • When the user registers, you generate an ephemeral secret prime for the user, and calculate the user's public prime: user_publicPrime.
    You then store the following cookies:
    ** The encrypted email address: user-access = Encrypt(user_email, DH_KDF(user_publicPrime, server_secretPrime))
    ** The user-specific public prime used for the Diffie-Hellman key agreement: user-prime = user_publicPrime

  • When you receive a request from the user, you use the values stored on the cookie to authenticate them: Decrypt(user_email, DH_KDF(user_publicPrime, server_secretPrime))

This will ensure that a new key is used for every user, and it will not require you to store user-specific passwords in your DB.

It still leaves singular users vulnerable to someone stealing their cookie and getting access to their account in perpetuity (user-access + user-prime will always produce a valid ciphertext).

If you want to prevent this from happening, I see no other alternative than storing user_publicPrime in the DB and associating it with the user_email. Whereby you'd invalidate the cookie by generating a new value of user_publicPrime and storing it in the DB.

If you do this, you could of course forgo the DH_KDF pattern altogether by simply saving user-specific server_secrets. Then again, you'd be storing cryptographic material in a DB. Not exactly something you want to do. With the DH_KDF pattern, you can keep 1 server_secretPrime stored somewhere secure, while user_publicPrime can be stored in the DB without concern.

[–]JasonCarswell 1 insightful - 2 fun1 insightful - 1 fun2 insightful - 2 fun -  (1 child)

> That's a cool concept.

/u/d3rr, is this something that can be done on other platforms? Projex, Federated PeerTube, Lemmy, etc?

[–][deleted] 2 insightful - 2 fun2 insightful - 1 fun3 insightful - 2 fun -  (0 children)

Sure, you could hack an alternate account/login system into anything open source.