On 6/07/2014 6:45 p.m., Nick Sabalausky wrote:
On 7/6/2014 1:00 AM, Rikki Cattermole wrote:
On 6/07/2014 6:06 a.m., Nick Sabalausky wrote:

Also, DAuth encourages passwords to be stored in a special structure:

   https://github.com/Abscissa/DAuth/blob/master/src/dauth/core.d#L311

which attempts to zero-out the password from memory as early as it can
(and encourages the user to populate it via char[] not string to avoid
having an un-wipable immutable plain-text copy in memory. See
'toPassword' vs 'dupPassword'). I'm certain the implementation can be
improved. And I'd kinda like to make it scoped if I can, instead of
refcounted. But it's something.

Obviously there are natural limits to these measures, so it can't
*guarantee* anything, only help guide the application developer. And it
doesn't/can't address all possible issues. But it's at least something.

For reference, Cmsed's password authentication that is built in will
automatically hash passwords and will not store in any way the plain
text version [0].
Also supports upgrading hashes as needed. From older algorithms to newer
preferred ones.

[0]
https://github.com/rikkimax/Cmsed/blob/master/source/user/cmsed/user/models/userauth.d#L57



Unfortunately, that doesn't really address the issue. The password
always has to come from somewhere in plaintext. By the time it gets to
*any* hashing function it's already existed in memory in plaintext.

No offense intended, but here's the thing:

That "class UserPassword" cannot even be *used* until the plaintext
password already exists in memory. It must get passed into UserPassword
(via opAssign) as a string. Problem is, AFAICS, nothing appears to be
removing that original plaintext copy from memory. Once it's in a
UserPassword object, the original copy *still* sits around waiting to
[maybe/eventually] get garbage collected or read by some bug/exploit.

Worse, that plaintext data is marked as immutable (because it's a
string), so it *cannot* be safely wiped from memory without breaking the
type system.

The idea behind the auto-zeroing Password type in DAuth: you do your
best to give it [hopefully] the one and only copy of the plaintext
password data, in mutable form, and DAuth nukes it from memory as soon
as it's able to. Not if/when GC kicks in, sweeps it, and reuses it. And
not just a copy of the data, but the actual [hopefully] original buffer.
Any further attempts (deliberate or accidental) to read that data
through any other reference will only receive zeros.

My reasoning is simple. Only upon setting the password for a user will the plaintext version ever be in memory or when logging in for authentication. Now this should be coming as a parameter via routes in some format as a string. If this cannot be caught by the GC and cleaned up, how exactly does your method help?

So as far as I'm concerned, if it cannot be cleaned up, there are bigger problems to worry about then just securing this one tiny piece of code.

Unless of course, we want some method to guard against this e.g. all data given to routes in Vibe is actually protected and will be forcefully freed upon finishing of the route.

On a different note though, it does seem I may have been hasty in
grouping RIPEMD in the "weak" category. I was unfamiliar with it and
assumed it was on par with MD5. A brief search seems to suggest that may
not necessarily be the case.

To me it was one of the *better* options available when I wrote it, hence it was my initial one.

Reply via email to