Recently I've been setting up libsodium in one of my projects by using cgo, in order to use the crypto_pwhash_str and crypto_pwhash_str_verify functions.
This has all gone very smoothly and I now have a small collection of functions that receive a []byte in the form of a plain-text password and either hash it, or compare it against another []byte to verify it.
My reason for using a []byte instead of a string is because, from what I've learnt so far about Go, I can at least loop over the plain-text password and zero all of the bytes, or even pass a pointer into libsodium's sodium_memzero function, in order to not leave it hanging around in memory longer than it needs to.
This is fine for applications where I have the ability to read input directly as bytes, but I'm now trying to use it in a small web application where I need to read passwords from a form using the POST method.
From what I can see in the Go source code and documentation, using r.ParseForm in a request handler will parse all of the form values into a map of strings.
The problem is that because strings in Go are immutable I don't think I can do anything about zeroing the memory of a password that was POSTed in the form; at least, using only Go.
So it seems like my only (easy) option would be to pass an unsafe.Pointer into a function in C along with the number of bytes and let C zero the memory for me instead (for example, passing it to the aforementioned sodium_memzero function).
I have tried this, and unsurprisingly it does of course work, but then I'm left with an unsafe string in Go, which, if used in a function like fmt.Println will crash the program.
My questions are as follows:
- Should I just accept that passwords will be POSTed and parsed as strings and that I shouldn't mess with it and just wait for the GC to kick in? (not ideal)
- Is zeroing the memory of a stringusing cgo ok, provided it's obviously documented in the code that the string variable should not be used again?
- Will zeroing the memory of a stringusing cgo ever do something like crashing the GC?
- Is it worth writing a sort of decorator for http.Requestthat adds a function to parse form values directly as[]byteso I have complete control over the values when they arrive?
Edit: To clarify, the web app and form POST is just a convenient example of a case where I might be handed sensitive data just from using Go's standard library in the form of a string. I'm more just interested in whether all of my questions are possible/worthwhile in some case were cleaning up data in memory as quickly as possible was more of a security concern.
 
     
     
    