Would you send a plain text password from your website to the server over a secure connection?

Muhamed G on November 03, 2017

What's your strategy when it comes to securing your web application's communications with the server? Do you just rely on HTTPS? Or you have an e... [Read Full]
markdown guide
 

Edit: I'm summarizing the discussion in the comments below, in the hopes that someone doesn't just read this comment and get the wrong idea.

Layering extra encryption on top of TLS/HTTPS doesn't add any security for traffic going across the wire. However, it may add extra security beyond the point where the TLS is terminated. For example, it prevents you from accidentally dumping sensitive information, like a password or a credit card number into a request log. It's all about considering what you're defending against, and what your likely attack vectors are. Extra encryption helps protect against attacks that would give the attacker access to your log data but that do not give them access to your main data store or the memory of you app servers. It can also help you be compliant with certain regulatory requirements, such as PCI (as it's now harder to accidentally leak the plaintext PAN info into a log).

If you do implement this extra encryption, be sure to use it sparingly - for instance, I wouldn't encrypt the entire request body, just the field I care about protecting. Also make sure that you protect those encryption keys - I would use asymmetric encryption with a keypair that is bound to the user's session and is never used for any other session. Avoid letting the secret key leave memory. If you have to persist is somewhere, for example to an external session store, make sure to encrypt it with a key-encrypting key. If you don't prevent that session private key from being accessed, you might as well not have the extra layer. It is for this reason that I wouldn't recommend that you layer this encryption in most cases, as proper key management is Hard.

Original Comment

When dealing with extra-sensitive information, such as Credit Card numbers, I like to encrypt on the client in addition to using HTTPS. I don't do it to protect against a man in the middle; if an attacker can read my HTTPS traffic, I'm already in trouble. Rather, I do it to prevent the cleartext from accidentally getting logged. I've noticed that we're usually pretty good about not logging those fields in areas where we're directly manipulating them, but it's too easy to later turn on some broader debug logging (like logging out all incoming request bodies) without realizing that we would then be leaking these values into our logs (not good, especially if that's the log file your PCI auditor decides to look at).

I've learned put up barriers like that make it harder to make a large mistake.

 

I'm sorry that this actually will not work as you cannot guarantee that the attacker will not decipher your client code and find your encryption keys -- thus making the encryption irrelevant. As long as you have an established https connection, its safe to sent passwords over the wire.

 

Didn't you read the comment? The encryption isn't to stop attacks, it's so that the sensitive information gets logged by accident on the client side it isn't just outputting plain text. Sure, a hacker could gain access to the server and if (big if) some sensitive data had been logged they could find it. But they'd still have to decrypt it.

And my guess is that the encryption keys aren't stored in the client, but instead sent over an HTTPS connection after the client is loaded.

Still, that does not protect a dedicated attacker to do both, first extract the encryption key from the client and attacking your server. The most difficult part is the big if here as you mentioned.

And my guess is that the encryption keys aren't stored in the client, but instead sent over an HTTPS connection after the client is loaded.

That proves that the HTTPS connection is trusted and it is equally safe to send passwords.

I know that, that's why I don't encrypt passwords on the client side. But my point is that the guy you're responding to doesn't do it for security against hackers. He does it for security against himself/his team in the event that they make a mistake which starts logging data received from the client. It doesn't have to be "securely" encrypted, it just needs to be encrypted at least a little to avoid violating PCI compliance.

As in all things in InfoSec, it's all about considering what kinds of attacks you're trying to defend against. In this case, I'm not trying to protect the data as it goes across the wire - I've already got TLS for that. If my TLS is busted, then I'm pwned. It also doesn't prevent code running in the browser from knowing the public half of the ephemeral, session-bound asymmetric keypair I'm using for the extra encryption, but if the attacker already has control of the user's browser, that user (and all of their data) is pwned. I'm also not really adding anything in the event of a complete compromise of my application server - if the attacker gains control over those, then I'm completely compromised, as they can query the DB and get my encryption keys to decrypt the data stored in the DB (no need to sit and monitor my logs when they can grab the whole batch of data proactively!).

All three of those things, though, are either hard (compromising TLS, complete control over the well-protected application server) or have a very small scope (control over the individual user's browser). What I'm trying to do by layering the encryption is getting rid of some of the low-hanging fruit and side-channel attacks that an attacker might use to gain some easy data.

One example of such a side-channel: I'm hoping that all of the servers in your request-handling chain (reverse proxies, app servers, database servers) are regularly patched and subjected to vulnerability scans and penetration tests. However, when's the last time anybody pentested their log aggregation servers? The real request data isn't passing through there, so often, they're forgotten in our hardening efforts. However, if we're logging request bodies that include sensitive information, suddenly that log server becomes a valuable target for an attacker. Adding an extra layer of encryption to that one piece of data helps prevent such a compromise. And even if we're also erroneously logging out all response bodies, we're still protected, since we use asymmetric encryption and the private key never leaves the app server's memory.

Another thing that is often neglected is security against an internal attacker. We spend most of our time and effort focused on external hackers, and very little - if any - on internal attackers. I've literally heard organizations state that their internal security policy is "We trust our people." If you want to see the fallacy in this, just look at what Twitter is in the news for today (an employee on their last day deleted Trump's Twitter account). Odds are, if your handling certain types of sensitive data (like credit cards), you already have to have procedures in place to prevent an internal attacker from getting to the main datastore (separating access to the database from access to the data-at-rest encryption keys, ensuring dual-control on both, etc.). However, have you locked down your log aggregation server with the same kinds of controls? Or, if you don't have one, are there people who have access to the server to view logs that don't have access to the database and the data-at-rest encryption keys?

To put it simply: there's no such thing as perfect security. There's just throwing up enough walls that the attacker moves on to easier prey.

I will say that I do not recommend that most people add extra encryption beyond TLS to most of their data. The false sense of security it could provide if you tried to use it everywhere might just be more damaging than not doing it at all. However, for high-value pieces of data, it could enhance security. I don't even think anyone should encrypt their entire request body, just the one extra-sensitive field.

Cool. Doesn't the PCI compliance require regular Pen tests and no storage of credit card information though?

It doesn't require "no storage" (at least, not of the PAN), just that we protect the storage (requirement 3.4 of PCI-DSS 3.2), which includes within log files. This strategy helps us achieve that. I was, however, trying to talk about a broader scope than just PCI, even if that's the specific case that I'm dealing with, hence the hoping that people are actually doing pen tests. Even within PCI, though, I wonder how many auditors have checked the pen test records for the log servers, as opposed to just checking them for the app servers and DBs. I don't trust my auditors to make my system secure any more than they trust me :).

When we had a pa dss audit every server had it's hard drive cloned and checked for anything matching the luhn algorithm. Lots of false positives but your solution seems like an excellent precaution.

 
 

When I think about it, it sounds perfectly reasonable.

 

I'm actually quite interested to hear from any internet security professionals here on dev.to, as I am not one. That said, I operate under the assumption that if a security precaution can be taken, it should be. Security is preventative.

Having an HTTPS connection is good, but skipping out on things like hashing and salting, using a strong (and professionally vetted) encryption algorithm, and nonces, leads to breaches. Sometimes important data is lost, and sometimes not. Regardless, I can't think of a situation in which a breach would be beneficial.

Security is important, and should not be an afterthought. Those are my two cents.

 

I would hope that people are encrypting their data on the server side. I think this question is asking "do you encrypt data on the client side before sending it over an HTTPS connection?"

 

Yeah I also undertand that the matter here is transport security

 

I'm not up to date to the new best practices, I'm using OAuth since forever, I think user/password is so antique.

A new threat I keep seeing is the Browser extension, this is one reason I would try to "hide" the password before sending, so it will not be stored in Analytics/Trackings by an extension.

 

So extensions can access a secured request sent from the website? including the body/ headers ..etc.?

 

I do not know the specifics yet, but there are many red flags, like Clipboard permissions are low priority on Chrome

Edge and Firefox doesn't even have the extensions permission system.

This week I caught an emoji extension spying which website I use.

Intercept HTTP requests in Firefox

get access to request headers and bodies, and response headers
cancel and redirect requests
modify request and response headers

 

Certainly not with passwords. If you hash at the client side, the hash essentially becomes your password. Plus a manual web request could store an unhashed version which would break your system. Plus the client would know the hash salt. It's all just a big mess you don't want to get in to.

 

If somebody has cracked your HTTPS connection, they can probably just inject a script onto the page that steals the password before it's even transmitted.

 

Excuse me but if that would happen right now, it would be the end of the Internet...

 

Sorry, shouldn't have used "cracked." There are ways to circumvent HTTPS other than cracking it, like a MITM attack which would allow injecting a script like I said.

Even in that case, it would be the end of the Internet. Unless the HTTPS connection is very flawed or tampered already or your CA is not trusted or you have a very flawed browser that would not happen. An already established TLS connection is a very secure medium.

Now in order to prevent edge cases vulnerable to MITM attacks its recommended to add extra security controls like HSTS and Public Key Pinning among other things.

Public key pinning is a good solution.

Also, I went to check out your site and your HTTPS certificate is invalid. You should probably fix that 😜

 

I use sha512 on the client and on the server (again) sha512 with a user specific salt to finally compare it with the hash stored in the database.
Besides "to be sure", this way the (plain) password is not being stored by the logger that saves all requests and response data of the API.

 

The client code can be read thus the hashed passwords in your logs are easy to decode.

 

Hi! How do you mean it will be easy to get access to my log server and use a sha512 rainbow table?

 

I would. But I will use transport security in all pages of the domain and enable security headers to begin with (for example a header that prevents your page being displayed inside a frame and others things that can be abused).

There are free and freemium tools that help you to check security headers and several other security checks to make to your page. Also read OWASP top ten ;)

Key pinning is the last thing to add but I have never implement it. You must know what you are doing there.

 

By the way what i mean with transport security in all pages is that the server must upgrade http to https inmediatly upon the first call and use a header that forces secure requests.

 

Sure I'll trust HTTPS. If that's hacked then we'd already be fucked up in so many different ways, that I wouldn't mind

 

Is it worth to encrypt the data if the the encryprion keys can be read from the client side?

 

only the encryption keys, not decryption, but there's no point, if https is broken anyone can just inject their own script

 

No need as long as world says https no longer secure.

 
code of conduct - report abuse