www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Erasing passwords from ram?

reply Dukc <ajieskola gmail.com> writes:
I am currently programming a server. So I got the idea that after 
I've generated all the hashes I need from a password, I want to 
erase it from RAM before discarding it, just to be sure it won't 
float around if the server memory is exposed to spyware by some 
buffer overflow. Is this wise caution, or just being too paranoid?

And if it is worthwhile, do I have to do this:
```
foreach(ref part; cast(ubyte[]) rootPassword) 
volatileStore(&part, 0);
```

Or, can I rely on that the compiler won't optimize this out?
```
rootPassword[] = '\0'
```

`rootPassword` is allocated on the heap, but only locally 
referred to.
Apr 30 2019
next sibling parent reply Kagamin <spam here.lot> writes:
You better obfuscate the password on client side.
Apr 30 2019
parent Dukc <ajieskola gmail.com> writes:
On Tuesday, 30 April 2019 at 08:31:40 UTC, Kagamin wrote:
 You better obfuscate the password on client side.
No, this particular password does not come from clients. Rather, it's given by server maintainer and used to generate passcodes that are then distributed to clients.
Apr 30 2019
prev sibling next sibling parent reply Cym13 <cpicard openmailbox.org> writes:
On Tuesday, 30 April 2019 at 08:15:15 UTC, Dukc wrote:
 I am currently programming a server. So I got the idea that 
 after I've generated all the hashes I need from a password, I 
 want to erase it from RAM before discarding it, just to be sure 
 it won't float around if the server memory is exposed to 
 spyware by some buffer overflow. Is this wise caution, or just 
 being too paranoid?

 And if it is worthwhile, do I have to do this:
 ```
 foreach(ref part; cast(ubyte[]) rootPassword) 
 volatileStore(&part, 0);
 ```

 Or, can I rely on that the compiler won't optimize this out?
 ```
 rootPassword[] = '\0'
 ```

 `rootPassword` is allocated on the heap, but only locally 
 referred to.
There are very few relevant threat models where removing a password from RAM is an adequate solution, I'm not sure it's worth the trouble. For comparison one case where it's considered important is removing the master password from a password manager from RAM to prevent another person finding the computer unlocked to recover it by memory inspection (which it would have the rigth to do since the process would be from the same user). That's quite specific and a server isn't nearly as exposed. That said, if you want to remove it, make sure to audit all functions that use it from the moment it enters memory to check that they don't make a copy for some reason (or use a type that doesn't allow copies). It's no use removing it at one place if it's still at another. In particular a pattern I see often is that you have a function that reads the password from a file/stdin/whatever onto the stack and sets on the heap the object you'll use throughout the program then returns. You will think of checking the use of that object, but may forget to clear the setter's buffer before returning leaving it in a stack's frame. You should also make sure that your compiler isn't recognizing that this part of memory isn't used later and optimizing away the overwrite call. This is lots of work for a vulnerability that should not be there and may not lead to memory disclosure even if it is present. I'd rather focus on mitigating that threat by keeping boundchecking on, writing safe code etc.
May 01 2019
parent reply Dukc <ajieskola gmail.com> writes:
Oops, I forgot to check back this theard. But yes, just the info 
I was looking for.

On Wednesday, 1 May 2019 at 22:14:52 UTC, Cym13 wrote:
 There are very few relevant threat models where removing a 
 password from RAM is an adequate solution.
Not an adequate solution... What else is usually needed? You can't mean hashing, because by definition one would not want to delete the password in the first place, if there weren't hashes made of it.
 I'd rather focus on mitigating that threat by keeping 
 boundchecking on, writing  safe code etc.
I do. I was just curious if doing this trick brings any practical extra safety. (By what I understood from your reply, yes with operating systems or password managers but not generally with servers, unless trying to guard it from it's maintainers) And I'm also going to try to follow Walter's safety tip number 1: never assuming the server won't crash. I'm going to make an automatic restarter process for it.
May 06 2019
parent reply Cym13 <cpicard openmailbox.org> writes:
On Monday, 6 May 2019 at 09:34:22 UTC, Dukc wrote:
 Oops, I forgot to check back this theard. But yes, just the 
 info I was looking for.

 On Wednesday, 1 May 2019 at 22:14:52 UTC, Cym13 wrote:
 There are very few relevant threat models where removing a 
 password from RAM is an adequate solution.
Not an adequate solution... What else is usually needed? You can't mean hashing, because by definition one would not want to delete the password in the first place, if there weren't hashes made of it.
 I'd rather focus on mitigating that threat by keeping 
 boundchecking on, writing  safe code etc.
I do. I was just curious if doing this trick brings any practical extra safety. (By what I understood from your reply, yes with operating systems or password managers but not generally with servers, unless trying to guard it from it's maintainers) And I'm also going to try to follow Walter's safety tip number 1: never assuming the server won't crash. I'm going to make an automatic restarter process for it.
The thing is, the most important concept in security is the threat model: what are you protecting against? There is no security without a threat model, protecting your data without first knowing from what makes absolutely no sense, so that question is paramount. Then we compare the cost of a successful attack and the benefit one gets from that attack: if the attacker can make a profit it's not secure. If the defense cost is greatly superior to the value of your asset it's not well spent and those resources should most likely be spent protecting against something else. From what I understand your threat model is that of a remote attacker finding a vulnerability leaking memory in a heartbleed fashion then finding credentials in that leaked memory providing access to sensitive resources. That's a rather constrained scenario which is good, but it's also a very rare scenario. Very few memory issues lead to memory leakage, especially while providing a way to control what is leaked. Memory corruption vulnerabilities (I include out-of-bound reading) generally either result in a crash or can be exploited for code execution. If an attacker has code execution on your server the impact is bigger than that of memory disclosure and erasing credentials from memory doesn't mitigate that. But those bugs are way more common than controlled memory disclosure. However the solutions to memory corruptions are the same whether you're trying to protect against code execution or memory disclosure. So what I'm trying to say is that, given your threat model, it does not seem relevant to protect against memory disclosure specifically: you want to protect against the larger and more common threat of memory corruptions and that happens to cover your current threat model. Unless what you want to protect is very very sensitive erasing passwords from memory would most likely be wasted time. But that's something that only you can assess.
May 06 2019
parent Dukc <ajieskola gmail.com> writes:
On Monday, 6 May 2019 at 17:57:55 UTC, Cym13 wrote:
 So what I'm trying to say is that, given your threat model, it 
 does not seem relevant to protect against memory disclosure 
 specifically: you want to protect against the larger and more 
 common threat of memory corruptions and that happens to cover 
 your current threat model.
Yes, I agree. So most important things are to keep boundscheck on, no plaintext passwords on hard disk and a restarter process separate from worker process. And no needless secrets on the server to protect in the first place, of course.
 Unless what you want to protect is very very sensitive erasing 
 passwords from memory would most likely be wasted time. But 
 that's something that only you can assess.
I assess that it's extra that won't hurt if I can easily do it and are in mood to, but I should not be pushing other work or kicking myself to implement it. Thanks for the analysis.
May 07 2019
prev sibling parent reply Nick Sabalausky <a a.a> writes:
On Tuesday, 30 April 2019 at 08:15:15 UTC, Dukc wrote:
 I am currently programming a server. So I got the idea that 
 after I've generated all the hashes I need from a password, I 
 want to erase it from RAM before discarding it, just to be sure 
 it won't float around if the server memory is exposed to 
 spyware by some buffer overflow. Is this wise caution, or just 
 being too paranoid?
I've seen this done, and regardless of likelihoods, it doesn't hurt as a precaution. The memutils lib offers a tool for this, 'SecureMem': http://code.dlang.org/packages/memutils In addition to memory-zeroing, it can also prevent it from getting "dumped to disk on a crash or during OS sleep/hibernation."
May 09 2019
parent Dukc <ajieskola gmail.com> writes:
On Thursday, 9 May 2019 at 19:10:04 UTC, Nick Sabalausky wrote:
 On Tuesday, 30 April 2019 at 08:15:15 UTC, Dukc wrote:
 I am currently programming a server. So I got the idea that 
 after I've generated all the hashes I need from a password, I 
 want to erase it from RAM before discarding it, just to be 
 sure it won't float around if the server memory is exposed to 
 spyware by some buffer overflow. Is this wise caution, or just 
 being too paranoid?
I've seen this done, and regardless of likelihoods, it doesn't hurt as a precaution. The memutils lib offers a tool for this, 'SecureMem': http://code.dlang.org/packages/memutils
Good link! The passwords in this case probably aren't worth it (see Cym's replies why), but I'll remember that library if I have to deal with something more sensitive, or just decide to put some extra effort to the security considerations.
May 10 2019