curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: credentials in memory

From: Dan Fandrich via curl-library <curl-library_at_lists.haxx.se>
Date: Sat, 19 Nov 2022 23:13:26 -0800

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
Received on 2022-11-20