Security at handling passwords

1,784 views
Skip to first unread message

Archos

unread,
May 20, 2012, 6:58:40 PM5/20/12
to golang-nuts
I've a program that saves temporary a password read from keyboard,
then it is passed to a function.

Note that in C, it's necessary remove the value of a temporary
password after of use it for greater security.

So, in Go, should be it initialized to zero after of its use? Does the
garbage collector could hold that variable in memory after of finish
the function?

Ugorji Nwoke

unread,
May 20, 2012, 7:03:48 PM5/20/12
to golan...@googlegroups.com
I would think using an array and zero'ing it when done should accomplish what you're trying to do.

a := [8]byte{}
// read password into a
for i := 0; i < len(a); i++ { a[i] = 0 }

Patrick Mylund Nielsen

unread,
May 20, 2012, 7:38:36 PM5/20/12
to Archos, golang-nuts
Short of using cgo, and actually freeing the memory you've used, there
is no easy way to do this in Go. There are no guarantees about when
stale objects will be garbage collected, so there is no easy way to
prevent somebody with access to the machine from retrieving such
passwords from memory. Your best bet is to use a []byte, and nil'ing
its contents after you're done, and not a string (which is immutable
and will linger in its entirety), although this still isn't as certain
as explicitly freeing the memory. (This is the way e.g. Java and C# do
it.)

Of course, on the other hand, Go's type-safety and automatic memory
management provide a lot of security benefits.

Patrick Mylund Nielsen

unread,
May 20, 2012, 7:45:40 PM5/20/12
to Ugorji Nwoke, golan...@googlegroups.com
This :)

Just remember it's moot if the password is passed as a string at any
point in your program.

Rémy Oudompheng

unread,
May 20, 2012, 8:10:30 PM5/20/12
to Patrick Mylund Nielsen, Archos, golang-nuts
On 2012/5/21 Patrick Mylund Nielsen <pat...@patrickmylund.com> wrote:
> Short of using cgo, and actually freeing the memory you've used, there
> is no easy way to do this in Go. There are no guarantees about when
> stale) objects will be garbage collected, so there is no easy way to
> prevent somebody with access to the machine from retrieving such
> passwords from memory. Your best bet is to use a []byte, and nil'ing
> its contents after you're done, and not a string (which is immutable
> and will linger in its entirety), although this still isn't as certain
> as explicitly freeing the memory. (This is the way e.g. Java and C# do
> it.)

Note that freeing memory as done in C code does not guarantee the
value is not accessible anymore (and similarly, being garbage
collected doesn't mean the value is erased from memory or unaccessible
by unsafe operations).

Rémy.

Patrick Mylund Nielsen

unread,
May 20, 2012, 8:26:22 PM5/20/12
to Rémy Oudompheng, Archos, golang-nuts
Thanks for clarifying Remy. I wasn't completely sure about cgo/GC
freeing. Also, to clarify, I don't mean that you should nil an array
or slice value, but rather the contents of the array(s).

Anyway, although you should use mutable data types to store sensitive
information, this is a relatively low-risk class of security problems.
(If a person can read your application's memory, they are likely able
to do much worse.) Instituting such a freeing mechanism/special byte
array would probably bring so many more serious stability problems to
"high-performance applications" to not be worth it.

Patrick Mylund Nielsen

unread,
May 20, 2012, 8:28:43 PM5/20/12
to Rémy Oudompheng, Archos, golang-nuts
*cue 20 professional cryptographers throwing their hands in the air*

On Mon, May 21, 2012 at 2:26 AM, Patrick Mylund Nielsen

Patrick Mylund Nielsen

unread,
May 20, 2012, 8:53:31 PM5/20/12
to Rémy Oudompheng, Archos, golang-nuts
FWIW here's .NET's description of its SecureString class
(http://msdn.microsoft.com/en-us/library/system.security.securestring.aspx)
which is automatically encrypted and memory-pinned, for when you want
to keep this kind of information around in memory:

"An instance of the System.String class is both immutable and, when no
longer needed, cannot be programmatically scheduled for garbage
collection; that is, the instance is read-only after it is created and
it is not possible to predict when the instance will be deleted from
computer memory. Consequently, if a String object contains sensitive
information such as a password, credit card number, or personal data,
there is a risk the information could be revealed after it is used
because your application cannot delete the data from computer memory.

A SecureString object is similar to a String object in that it has a
text value. However, the value of a SecureString object is
automatically encrypted, can be modified until your application marks
it as read-only, and can be deleted from computer memory by either
your application or the .NET Framework garbage collector."

Of course, this requires the OS hiding the encryption key somehow/in
kernel space. And of course, constructing a SecureString from
something that used to be a string, or getting a string with
ToString(), causes the same problem as before.

http://blogs.msdn.com/b/shawnfa/archive/2004/05/27/143254.aspx
http://blogs.msdn.com/b/shawnfa/archive/2004/05/17/133650.aspx

On Mon, May 21, 2012 at 2:28 AM, Patrick Mylund Nielsen

Reinhard Wobst

unread,
May 21, 2012, 6:39:38 AM5/21/12
to golang-nuts
Depending of what you want to do with the password - for
authentication, there is a simple way when you use a hashed and salted
password only: simply hash the bytes typed in incrementally, so only
the last character is kept in memory (which can be nulled if you
want). Of course, then no erase is possible when you type in the
password, but you are more or less secure with minimal effort. This
also solves the problem that memory could be swapped (e.g., you have
to boot with an option "noswap" and so on).

Just an idea ...

Reinhard

Damian Gryski

unread,
May 21, 2012, 7:49:10 AM5/21/12
to golan...@googlegroups.com


Le lundi 21 mai 2012 01:03:48 UTC+2, Ugorji Nwoke a écrit :
I would think using an array and zero'ing it when done should accomplish what you're trying to do.

a := [8]byte{}
// read password into a
for i := 0; i < len(a); i++ { a[i] = 0 }

   Note that the Cipher interface used to have a Reset() routine that just did this.  It was removed as part of issue 2841 ( http://code.google.com/p/go/issues/detail?id=2841 ) because in agl's words:

"Reset(): Since the garbage collector can copy memory around at will, and it can be swapped out etc, I fear that Reset() is promising something that we can't deliver and so should be removed."

Damian
 

Patrick Mylund Nielsen

unread,
May 21, 2012, 8:06:43 AM5/21/12
to Damian Gryski, golang-nuts, a...@golang.org
Yep. AFAIK it's the same situation in Java.

At least you're unlikely to leak whole strings containing passwords if
you use and zero a byte array.

Would it be feasible to add a kind of byte array whose contents can be
explicitly freed? I don't know. Perhaps agl has some thoughts on this?
I imagine he's given it some thought considering he's written most of
the crypto code in Go.

Then again, it might not be possible at all with Go's memory model, or
cause a slew of problems after people use it to "get performance".

Archos

unread,
May 21, 2012, 8:15:56 AM5/21/12
to golang-nuts

On May 21, 12:49 pm, Damian Gryski <dgry...@gmail.com> wrote:
> Le lundi 21 mai 2012 01:03:48 UTC+2, Ugorji Nwoke a écrit :
>
> > I would think using an array and zero'ing it when done should accomplish
> > what you're trying to do.
>
> > a := [8]byte{}
> > // read password into a
> > for i := 0; i < len(a); i++ { a[i] = 0 }
>
>    Note that the Cipher interface used to have a Reset() routine that just
> did this.  It was removed as part of issue 2841 (http://code.google.com/p/go/issues/detail?id=2841) because in agl's words:
>
> "Reset(): Since the garbage collector can copy memory around at will, and
> it can be swapped out etc, I fear that Reset() is promising something that
> we can't deliver and so should be removed."
Then, the only solution that I see is turn off the garbage collector
while you're handling sensitive information.

Adam Langley

unread,
May 21, 2012, 11:09:34 AM5/21/12
to Patrick Mylund Nielsen, Damian Gryski, golang-nuts
On Mon, May 21, 2012 at 8:06 AM, Patrick Mylund Nielsen
<pat...@patrickmylund.com> wrote:
> Would it be feasible to add a kind of byte array whose contents can be
> explicitly freed? I don't know. Perhaps agl has some thoughts on this?
> I imagine he's given it some thought considering he's written most of
> the crypto code in Go.

If you have a special case where you really want to zero out the
memory then you should write a package that calls mmap and mlock
directly. In general, however, the memory model is such that the
runtime may copy memory around and the kernel can swap pages out.
Maybe that's ok for some applications who consider it better than
nothing, but it's not guaranteed.


Cheers

AGL

Mike Samuel

unread,
May 22, 2012, 2:23:59 PM5/22/12
to golan...@googlegroups.com


On Sunday, May 20, 2012 7:03:48 PM UTC-4, Ugorji Nwoke wrote:
I would think using an array and zero'ing it when done should accomplish what you're trying to do.

a := [8]byte{}
// read password into a
for i := 0; i < len(a); i++ { a[i] = 0 }

If a GC compact happens between reading and zeroing then there can be multiple copies in memory for an arbitrary amount of time -- the old value which is no longer pointed to and which won't be zeroed by that code, and the compacted value which is pointed to and zeroed.

Mike Samuel

unread,
May 22, 2012, 2:36:26 PM5/22/12
to golan...@googlegroups.com


On Tuesday, May 22, 2012 2:23:59 PM UTC-4, Mike Samuel wrote:

If a GC compact happens between reading and zeroing...

Please ignore.  I forgot that Go GC is non-compacting. 

Jiří Zárevúcky

unread,
May 22, 2012, 2:52:46 PM5/22/12
to golan...@googlegroups.com
I think that can change at any time. I wouldn't rely on a particular GC implementation when it comes to security.

awn...@gmail.com

unread,
May 1, 2017, 8:41:48 AM5/1/17
to golang-nuts
I was looking for a solution to the same problem and couldn't find one. So I made a library that you might find useful:

https://github.com/libeclipse/memguard

It's pure Go, thread-safe, and supports all major operating systems.
Reply all
Reply to author
Forward
0 new messages