On Fri, Sep 30, 2022 at 09:43:39AM +0200, Daniel Stenberg via curl-library wrote: > libcurl hold credentials (passwords for servers and proxies) in memory in > clear text, potentially for a long time. If something goes wrong and that > memory is accessed by an external party, things would be bad. > > Is it worth doing something about?
It's important to define what exactly the threat is we want to protect against. These are the main ones I can think of: 1. local attackers with access to the process & its memory 2. local attackers with access to memory, core dumps, swap space or hibernation files 3. remote attackers tricking curl into returning secrets from memory (via a Heartbleed-style attack or by returning uninitialized stack or heap space, for example) In the 1. case, if an attacker can access the process' resources and memory, there's not much left to protect. If the attacker has the same rights as the process, then everything that curl can access, including passwords, the attacker can, too. Even if secrets are encrypted, the attacker has access to the same decryption keys as the real process so he can just decrypt them. I don't see any way to protect against this in the general case. However, if the attacker somehow only has access to the memory and not the rest of the process' assets (case 2.), then use of a hardware security device can protect the keys from directly being stolen, But, there will be some times that curl needs the raw secrets in order to pass them to other dependencies or write them into buffers, and when they're in memory, the attacker can still get them. And if they're in memory, then can end up on disk in a core or hibernation file where the attacker can read them. The 3. case is the most interesting one that this proposal could help mitigate. A Heartbleed-style bug that gives arbitrary memory to an attacker could return memory containing a secret. If secrets are not stored in plaintext in RAM, then it becomes much harder to obtain those secrets. But it's still not perfect. Here are some possible mitigations we could implement in curl: 1. Clearing secrets with memset once their need is over. If the secrets are out of RAM, they won't end up in core files, swap files or process debuggers. However, curl needs some secrets for the entire lifetime of the process (e.g. proxy credentials) so it can't clear all of them all the time. Also, curl needs them in RAM for a short time to use them before they're cleared, so an attacker could just grab them at that time. 2. Creating a random session key at startup and encrypting secrets as soon as possible using that key. This suffers from the same problem mentioned before, in that the secrets have to be decrypted to use them, even if only for a short time. Also, encrypting many secrets using the same key makes it easier for an attacker to guess that key. So, a Heartbleed-style attack that is able to obtain many encrypted secrets could still obtain the decryption key. 3. Creating a new random key for each secret. This avoids the key reuse problem in mitigation 2. by creating a new, random key for each and every new secret that needs to be protected. The overhead is greater but it's more secure. However, those random keys are still stored in RAM so a Heartbleed-style attack that obtains the encrypted secrets might at some point also obtain the decryption keys as well, exposing those secrets. 4. Storing the random keys from 3. in a hardware security module. This avoids the possibility that the attacker might obtain the decryption keys by storing them in an HSM. Unfortunately, curl still needs to decrypt them eventually and they'll be in RAM for at a least a short time while that happens, during which time they're still subject to being obtained by an attacker. So, no matter how much we are able to protect those keys, they'll still be vulnerable to an attacker. All we can do is reduce the time that they're vulnerable, which just increases the time an attacker needs to get them, not whether or not they *can* get them. Still, reducing the time could turn a practical, but slow, attack into an impractical one. And, unless applications do the same that curl does, these mitigations are of limited use since the application itself becomes the weak link in the chain. But, if libcurl does something then we can at least point our fingers elsewhere if the application doesn't take the same amount of care. We also need to consider the costs of implementing a solution: implementation costs, maintenance costs, increased difficulty in debugging, performance degradation, portability, etc. This isn't my area of expertise, and I'm sure there have been many PhDs theses written on exactly what I'm speculating about above. It's a complicated topic, and we should have a clear idea of the benefits of retrofitting some kind of protection into curl before doing it. Dan -- Unsubscribe: https://lists.haxx.se/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html