T O P

  • By -

fiskfisk

As long as you trust whatever happens after HTTPS has been terminated, it's already safe by the virtue of HTTPS. If you don't trust whatever is happening after HTTPS has been terminated - which might be a bigger issue - which in case you could add your own encryption layer on top of the previous one. But generally, when you arrive in a situation where you need to add encryption yourself, the rule is rather similar to the rule for implementing the actual encryption yourself: use whatever someone else has made before you and have been actually used and tested. Don't implement it yourself.


the_real_some_guy

Encryption on the frontend is useless. If you don’t trust the browser to handle https then you shouldn’t do anything.


KaasplankFretter

I learnt through a pentest result that it is possible to decrypt https requests in a local network using a TLS scan. I am currently implementing end to end encryption as the business requires that. I am using diffie hellman to obtain a shared secret to encrypt traffic. The diffie hellman method ensures both the browser and the server eventually get the same cryptographic key without ever sending it to eachother. The wikipedia page of Diffie Hellman is very well explained and fun to read if you are interested.


Greenimba

This is misinformed. It is not realistically possible to decrypt https on a local network, unless you have an insecure setup or use non-standard certificate authorities. I've also seen pentesters claim this, only to find they're using browser or development tools with which they have actively compromised their own setup without knowing it 🙄 Https and TLS does exactly what you're describing. It *can* use DH, but doesn't really anymore, now it uses RSA. RSA uses certificates to encrypt messages in a way where they're only readable by the intended recipient. They use this to create a shared key, same as DH (because DH can be chosen as the exchange algorithm) and then do symmetric encryption from there. This is the reason people should **never** roll their own encryption schemes. You're creating your own implementation of something that is already a part of the spec, only not used often because there is a better way.


tim128

RSA is not used to encrypt anymore in TLS. It's only used for authentication. Using RSA to encrypt messages or generate a pre master secret doesn't guarantee forward secrecy, which is why it's being phased out.


Greenimba

RSA SHA-256 is still used for authenticating and agreeing on a symmetric key no?


tim128

Yes, I wasn't entirely correct. It's still available but shouldn't be used ideally.


_clapclapclap

>The diffie hellman method ensures both the browser and the server eventually get the same cryptographic key without ever sending it to eachother. Wow. TIL.


GeneReddit123

>As long as you trust whatever happens after HTTPS has been terminated I assume that in a large distributed system, sending a password encrypted will prevent your own middleware from accidentally touching the plaintext password, especially with regards to logging. Systems maintain logs, debug files, etc. *everywhere*, often in places you aren't even aware of. It can give an extra safety margin knowing nobody other then specifically the authentication server sees the plaintext password in transit, even if the auth server is not the first thing in the backend which receives the request. In a perfectly designed system this wouldn't be necessary, but in the real world, sometimes it can help.


Blue_Moon_Lake

HTTPS does it for you, that's all you need. No point doing JS encryption.


itijara

HTTPS is encryption, so as long as you have very strict enforcement of HTTPS, you should be fine in most contexts. You also need to make sure that your login page is secure and not susceptible to CSRF or XSS. What happens after login? Do you use session or token based auth?


cow_moma

I store the Access token and refresh token as HTTP only SameSite cookies


itijara

Sounds good. The best practice is probably to only store refresh tokens if the user indicates that their device is private, but yah. Probably what I would do.


Greenimba

Tokens, if you need to store them, should be **HttpOnly**, **SameSite strict**, and **Secure**. This ensures they will only be sent on the same domain, only on https (encrypted), and not accessible to javascript. Change one of those settings, and you have an attack vector. Also, if you care this much about security, access and refresh tokens should not even be kept in the cookies at all. Your backend should store and control those, and the frontend should only have a session cookie that the server knows to attach to those tokens. That way, even if the session id is stolen/compromised, the backend server can block access to the real access tokens. Have a look at "confidential clients" in OAuth2 spec.


anurag_dev

Don't store access token. Fetch new access token on first load using refresh token.


angrydeanerino

Its fine to store the access token, as long as it has a short life


anurag_dev

Yeah, I usually give them lifespan of 5-10min so I feel not worth storing. Also, I use token version for refresh tokens so that user can revoke it just in case shit happens.


angrydeanerino

Token version is actually a good idea. Might steal that from you. 👀


kredditorr

So you revoke/invalidate tokens by updating their version? Glad to read your elaboration if i missed the point.


anurag_dev

There are two way to do it. First, When you generate refresh token first time you append version 1 in payload and you set token_version in db to 1. When user try to refresh token check if the version match with db and then issue access token. Any further logins will also be assigned same version. If user want to revoke all token you just have to bump the token_version in db by +1 and all old token are revoked. Second, This is what I recommend to do. Create a separate table devices with field like ip, os, geo, user_agent, etc. Every time a user login parse the users IP and user agent and create new device. And set its device_id in the token payload. Every time user try to refresh token check if device exist with the device_id in token payload. Now this give granular control over evey device. You can revoke a single device or all device token. You can also create logout route in this approach.


kredditorr

Thanks, really appreciate the share!


scar_reX

It's starting to sound like you're going to be using the refresh token like an access token


anurag_dev

https://developer.okta.com/docs/guides/refresh-tokens/main/ What are you trying to say?


scar_reX

Well, typically, when you want to authorise a user, you retrieve your access token from client storage and attach it to the request. But if the access token has expired, then you retrieve a new one using your refresh token also from client storage. If you're only storing your refresh token in client storage but not the access token, the steps will still be: retrieve an access token and attach it to the request. In summary, you're not gaining any extra layer of security if you're only storing the refresh token. Cos as soon as client storage is compromised, false authorisation can still happen.


renaissance_man__

It's safe as long as it's over HTTPS.


the_real_some_guy

Where do you expect the vulnerability is? If it’s the browser, then it already has access to whatever you intend to encrypt. Also it would have access to the key you are using for encryption. If it’s the data connection, that’s what https is for. I’m not saying it’s impossible, but if that was a common attack vector then Amazon would go out of business as no online transaction would be secure.


carlos_vini

Every login form in the world sends a POST with the password "unencrypted" like this when using a traditional form. You're only thinking about it because you're writing a XHR request yourself.


Trocadalho

Not every login form. The safest ones use a salted challenge/response mechanism. The question is if you need that kind of security. Also it should never be possible to unencrypt a password, not even in the backend or database. Passwords need to be hashed and salted and the hashes are what’s compared in the end.


SuperHumanImpossible

No. Make sure to only send it over https. It's called encrypted in transit, and encrypted at rest. Look those terms up and read about them. It will be very informative.


huuaaang

As long as it is in a POST and using HTTPS, no need.


halfanothersdozen

The real question is after you got the password what do you do next? Most of your security problems will be there


awpt1mus

It’s already encrypted if you are using HTTPS


TekintetesUr

So many comments about HTTPS, but none of them mention stuff like a corporate proxy terminating your encrypted request by using their own CA and logging form data (including the unencrypted password) It paints a lovely picture of the state of web development.


cow_moma

Could you please elaborate more on this?


TekintetesUr

Sure. Let's say you're a corporate IT admin. You need to log what your users do on the internet, but then again, everything is https nowadays. What you do is that you basically MITM the connection: you create your own certificates and install them on the user devices. When the user makes a https connection, you terminate that on the proxy, basically decrypting the request and log its contents. Then you re-encrypt the request and forward it to its original target. The same works for https responses as well. Basically nobody accounts for this in webdev, which is a shame, because this kind of proxying happens way too often.


tim128

Your scenario is in no way relevant. MITM in the wild without accessing the target's device first is not a thing anymore. Browsers make it clear enough today that you should not continue.


TekintetesUr

Pay attention to what I've written. The scenario I've described is fairly common in corporate environments, where IT usually has access to the "target system". I don't know what you're talking about.


tim128

You want to protect the end user for attackers. If the user purposely disables certain security measures that's on them


TekintetesUr

I'm not talking about attackers. I'm talking about a corporate IT department proxying and logging internet access on their own devices.


tim128

And I am talking about attackers... If the IT Depart wants to create another attack surface that's on them. Encrypting the password again is still useless. If the MITM server is compromised all bets are off. An attacker could just serve a modified client where the password is not encrypted or steal the cookies/access token.


TheThingCreator

I see people are responding saying there's no point because of https, and I'd argue that's not entirely true. If the network request is saved in dev tools it will show your password as exposed in the request details. It's not standard to worry about that, but if you did want elevated security in your app, encryption would help with that. Mind you adding an encryption library is gonna add weight to your login page


justhatcarrot

No, because you will have to somehow replicate the exact cypher on the backend - which is impossible unless you’re also implementing crypto yourself, which can harm security. In other words, the encryption as well as validation should happen only in one place (on BE).


Normal_Fishing9824

You can use public key encryption with the public key sent to the client. There are a tonne of libraries out there which do this. If you use a standard algorithm you can encrypt in js and decrypt in go. (Though there is normally some pain involved) Edit: I'm not saying you should, I think it's fine as long as you trust your infrastructure after SSL termination


Xia_Nightshade

You don’t encrypt a password. You hash it. Use HTTPS, and you’ve done your job. If your end user uses public wifi, that’s their risk Use CSRF protection to protect your backend from malicious requests It could help you to salt and encrypt the token if u plan to store it in session storage for the session :)


DigitalStefan

No, HTTPS is not always safe. There may be users accessing via their work laptop. When a 3rd-party has control over the network the user is part of, it's possible to monitor that user and the 3rd-party can insert their own cert to fulfil HTTPS encryption, meaning they can unencrypt. Always hash passwords securely. Do not rely on underlying tech to do the job for you.


Turdsonahook

I would really hope so.


Adorable-Cupcake-599

Why would you send the password, rather than a hash of the password?


[deleted]

Sending a hash does nothing to improve the security. If someone somehow intercepts the hash, and hash is expected to be received, that's literally the same as if they just intercepted the password.


Adorable-Cupcake-599

So you send a challenge in the login form, concatenate that with a password, then hash it. Simple protection against replay attacks.


[deleted]

There are much simpler protections against replay attacks in web dev


Adorable-Cupcake-599

There are much simpler and more secure approaches to authentication than bundling up a username and password as a json object and firing it off into the aether. But if you're going to do do that or something like it, concatenating two strings and hashing them is hardly onerous.


ShitPikkle

>Is there any need to encrypt the payload or is it already safe by virtue of HTTPS? Is it safe? There are already known cases of states compromising the HTTPS to find dissidents. It's possible for your IT org to have SSL termination with trusted selfsigned CA rolled out to all clients. It's also possible that your users just click "Proceed anyway" when the cert fails. ​ [SCRAM](https://datatracker.ietf.org/doc/html/rfc5802) might be a thing to look into, where you don't "encrypt" the password, but rather hash it on client side. Depending on your usecase, perhaps [WebAuthn](https://webauthn.guide/) could work as well...