PASSWORD_HASHERS attempt to look up empty algorithm in certain cases
|Reported by:||wdoekes||Owned by:||nobody|
|Cc:||wdoekes||Triage Stage:||Design decision needed|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
the Django 1.4+ PASSWORD_HASHERS lookup conflicts with $1$<salt>$<password> (md5crypt) style hashes.
I'm using Modoboa which uses it's own auth first and falls back to Django auth if passwords don't match. For the aforementioned hash the algorithm detected becomes '' (the empty string).
if len(encoded) == 32 and '$' not in encoded: hasher = get_hasher('unsalted_md5') else: algorithm = encoded.split('$', 1) hasher = get_hasher(algorithm)
if ((len(encoded) == 32 and '$' not in encoded) or (len(encoded) == 37 and encoded.startswith('md5$$'))): algorithm = 'unsalted_md5' else: algorithm = encoded.split('$', 1)
ValueError: Unknown password hashing algorithm ''. Did you specify it in the PASSWORD_HASHERS setting?
I thought I could fix that by adding a custom hasher which always returns False, but that fails because I'm not allowed to use the empty name for algorithm.
ImproperlyConfigured: hasher doesn't specify an algorithm name: modoboa.auth.hashers.NoAlgorithmHasher
To fix this, I either need it to refuse the empty algorithm (fix1.patch), or allow the empty algorithm (fix2.patch, where I'll have my bogus hasher return false later on).
In both cases the fixes are trivial.
As an aside, the current if not getattr(hasher, 'algorithm') looks like a typo. I'd go for either if not hasher.algorithm or if not getattr(hasher, 'algorithm', None).
if not getattr(hasher, 'algorithm'): raise ImproperlyConfigured("hasher doesn't specify an " "algorithm name: %s" % backend)
Change History (8)
comment:1 Changed 2 years ago by claudep
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
- Triage Stage changed from Unreviewed to Design decision needed
- Type changed from Uncategorized to New feature