Right now, Django's auth system pretty much uses sha1 hardwired in (literally, in the case of User.set_password) for the hash. For a discussion of why a general-purpose hash function is not the best idea in the world for password encryption, see:
I'd like to propose a backwards-compatible method of allowing different hash algorithms to be used, while not adding new dependencies on external libraries to the core.
1. Add a setting DEFAULT_PASSWORD_HASH. This contains the code for the algorithm to use; if it is absent, 'sha1' is assumed.
2. Add a setting PASSWORD_HASH_FUNCTIONS. This is a map of algorithm codes to callables; the callable has the same parameters as auth.models.get_hexdigest, and return the hex digest its parameters (to allow for a single function to handle multiple algorithms, the algorithm aprameter to get_hexdigest is retained). For example:
3. auth.models.get_hexdigest is modified such that if the algorithm isn't one of the ones it knows about, it consults PASSWORD_HASH_FUNCTIONS and uses the matching function, if present. If there's no match, it fails as it does currently.
4. User.set_password() is modified to check the value of DEFAULT_PASSWORD_HASH, and uses that algorithm if specified; otherwise, it uses 'sha1' as it does not. (Optional: Adding the algorithm as a default parameter to User.set_password().)
On Sat, Nov 27, 2010 at 10:14 PM, Christophe Pettus <x...@thebuild.com> wrote: > Right now, Django's auth system pretty much uses sha1 hardwired in (literally, in the case of User.set_password) for the hash. For a discussion of why a general-purpose hash function is not the best idea in the world for password encryption, see:
Completely leaving aside the potential benefit of allowing different hash algorithms, I think the specific argument made by the author of that article, along with their proposed solution of an "intentionally slow" algorithm, is the wrong approach. Your application ends up just as hobbled by such an algorithm as a potential attacker. If you're choosing a slowdown factor based on your worst-case attacker, you're likely to significantly impair the ability of a website running on hardware that's not as fast, especially if you're authenticating users all the time.
I think there are better potential solutions to concerns about password cracking. Django already salts the hashes, which is asymmetrical in a good way: it helps complicate brute force attacks without slowing down Django's ability to test a given password. Better password policies can also help; e.g., each additional letter you require in your users' passwords exponentially increases the space of passwords that need to be brute-forced. In cases where your attacker doesn't have direct access to the database, you can greatly slow them down by only allowing a certain amount of login attempts in a given time period.
> Your application ends up just > as hobbled by such an algorithm as a potential attacker.
Actually, no, the situations are really quite asymmetrical. In order to brute-force a password, an attacker has to be able to try many, many thousands of combinations per second. To log in a user, an application has to do it exactly once. A hash computation time of, say, 10ms is probably unnoticeable in a login situation, unless you have tens of thousands of users logging in per minute (and if this is the case, then you probably have other problems than the speed of your password hash algorithm). But that would pretty much slam the door down on any brute force attempt at a password recovery.
> Django already salts the hashes, which is > asymmetrical in a good way: it helps complicate brute force attacks > without slowing down Django's ability to test a given password.
A salt is of no benefit on a brute force attack; it's function is to prevent dictionary attacks, which are a different animal.
And if you are willing to assume that no attacker can ever get access to your database, then you don't have to hash the password at all.
But, as you point out, that's a separate discussion from the value of pluggable encryption algorithms. There was a time that MD5 was the perfect answer; now, it's SHA-1. Different applications will have different needs as far as how they write the passwords to disk, and having an architecture to handle this seems like a good idea.
On Sat, Nov 27, 2010 at 11:47 PM, Christophe Pettus <x...@thebuild.com> wrote: > Actually, no, the situations are really quite asymmetrical. In order to brute-force a password, an attacker has to be able to try many, many thousands of combinations per second. To log in a user, an application has to do it exactly once. A hash computation time of, say, 10ms is probably unnoticeable in a login situation, unless you have tens of thousands of users logging in per minute (and if this is the case, then you probably have other problems than the speed of your password hash algorithm). But that would pretty much slam the door down on any brute force attempt at a password recovery.
But how far are you willing to go in your assumption of the worst-case computational ability of your attacker? Would tuning the hash to (say) a 10ms delay for your web server's modest hardware translate into a significant delay for an attacker with far more resources? (This isn't a rhetorical question; I honestly don't know.)
> A salt is of no benefit on a brute force attack; it's function is to prevent dictionary attacks, which are a different animal.
It does in fact slow down brute force attacks against multiple encrypted passwords; each password with a different salt is within an entirely different space that needs to be brute forced separately from the other passwords.
> And if you are willing to assume that no attacker can ever get access to your database, then you don't have to hash the password at all.
Sure, but my point was that there are various walls you can throw up against attackers to slow them down that don't involve slowing down your hash algorithm.
> But, as you point out, that's a separate discussion from the value of pluggable encryption algorithms.
Right; I didn't mean to dissent from (or concur with) that proposal.
> But how far are you willing to go in your assumption of the worst-case > computational ability of your attacker? Would tuning the hash to > (say) a 10ms delay for your web server's modest hardware translate > into a significant delay for an attacker with far more resources? > (This isn't a rhetorical question; I honestly don't know.)
Let's do the math. The space of eight alphanumeric character passwords is 2.8e12. Even assuming you can cut two orders of magnitude off of that with good assumptions about the kind of passwords that people are picking, this means that the attacker has to run about 28 billion times more computations that you do. At 10ms per password, it would take them about 447.8 years to crack a single password, assuming hardware of equivalent speed.
> It does in fact slow down brute force attacks against multiple > encrypted passwords; each password with a different salt is within an > entirely different space that needs to be brute forced separately from > the other passwords.
Remember how a brute force attack works. Given a hash x, the attacker does:
hash('00000000' + salt) = x? No, then, hash('00000001' + salt) = x? No, then, ...
The only benefit of the salt here is that it makes the string to be hashed a bit longer, but the benefit is linear, not exponential.
A dictionary attack works by consulting a precomputed set of passwords and their hashes, (pwd, hash(pwd)). The attacker then runs down the dictionary, comparing hashes; if they get a hit, they know the password. The salt defeats this by making the pwd -> hash(pwd) mapping incorrect. -- -- Christophe Pettus x...@thebuild.com
I wrote: > A dictionary attack works by consulting a precomputed set of passwords and their hashes, (pwd, hash(pwd)). The attacker then runs down the dictionary, comparing hashes; if they get a hit, they know the password. The salt defeats this by making the pwd -> hash(pwd) mapping incorrect.
I'm being slightly inaccurate here; what I'm describing above is a rainbow dictionary attack, rather than just a plain dictionary attack (which is a brute force attempt on the password over a limited range of input values). Anyway, a salt isn't helpful for a plain dictionary attack, either, for the same reason as a brute force attack.
Anyway, back to the discussion of the actual proposal. :) -- -- Christophe Pettus x...@thebuild.com
On Sun, Nov 28, 2010 at 12:19 AM, Christophe Pettus <x...@thebuild.com> wrote: > Let's do the math. The space of eight alphanumeric character passwords is 2.8e12. Even assuming you can cut two orders of magnitude off of that with good assumptions about the kind of passwords that people are picking, this means that the attacker has to run about 28 billion times more computations that you do. At 10ms per password, it would take them about 447.8 years to crack a single password, assuming hardware of equivalent speed.
The point is that I'm *not* assuming hardware of equivalent speed. I'm assuming that a worst-case attacker has hardware significantly faster than your webserver at their disposal, so I was curious if the purported benefit still held in that case. Maybe it does; I don't know.
>> It does in fact slow down brute force attacks against multiple >> encrypted passwords; each password with a different salt is within an >> entirely different space that needs to be brute forced separately from >> the other passwords.
> Remember how a brute force attack works. Given a hash x, the attacker does:
> hash('00000000' + salt) = x? No, then, > hash('00000001' + salt) = x? No, then, > ...
> The only benefit of the salt here is that it makes the string to be hashed a bit longer, but the benefit is linear, not exponential.
I'm not arguing that a salt helps against brute-forcing a *single* password (it doesn't), but it does in fact help against someone trying to brute-force your entire password database (or any subset of more than one password), since each password with a different salt lies within an entirely different space that must be brute-forced separately from the rest.
> Anyway, back to the discussion of the actual proposal. :)
Sure, I didn't mean to veer things too far off course here; even assuming the bcrypt argument doesn't hold, it's entirely possible that someone may want to easily plug in SHA512/SHA3/whatever into their password encryption.
> The point is that I'm *not* assuming hardware of equivalent speed. > I'm assuming that a worst-case attacker has hardware significantly > faster than your webserver at their disposal, so I was curious if the > purported benefit still held in that case. Maybe it does; I don't > know.
Well, yes, it does, for exactly the reason described: The application has to encode exactly one password; the attacker has to try billions in order to brute-force one. If you assume, say, one password per week is the slowest practical attack, and if it takes 10ms to hash one password, the attacker's hardware has to be about 46,654 times more powerful than your web server.
> I'm not arguing that a salt helps against brute-forcing a *single* > password (it doesn't), but it does in fact help against someone trying > to brute-force your entire password database (or any subset of more > than one password), since each password with a different salt lies > within an entirely different space that must be brute-forced > separately from the rest.
I'm not sure what you mean by the "space"; I think you are thinking of a rainbow dictionary attack, where the hashes are precomputed; a salt does indeed help (and probably blocks) that kind of attack. In the case of a straight brute-force attack or a standard dictionary attack without precomputing, the only benefit of the salt is that it makes computing the candidate hash a bit longer, based on the length of the salt. It's a trivial amount of time.
Remember, it's extremely inexpensive to brute-force a single MD5 or SHA1 hash, and the salt does not make it appreciably more expensive. If a CUDA application can brute force 700 million MD5s per second, doubling the length is not really going to make it any more secure.
On Sun, Nov 28, 2010 at 12:11 PM, Christophe Pettus <x...@thebuild.com> wrote: >> I'm not arguing that a salt helps against brute-forcing a *single* >> password (it doesn't), but it does in fact help against someone trying >> to brute-force your entire password database (or any subset of more >> than one password), since each password with a different salt lies >> within an entirely different space that must be brute-forced >> separately from the rest.
> I'm not sure what you mean by the "space"; I think you are thinking of a rainbow dictionary attack, where the hashes are precomputed; a salt does indeed help (and probably blocks) that kind of attack. In the case of a straight brute-force attack or a standard dictionary attack without precomputing, the only benefit of the salt is that it makes computing the candidate hash a bit longer, based on the length of the salt. It's a trivial amount of time.
> Remember, it's extremely inexpensive to brute-force a single MD5 or SHA1 hash, and the salt does not make it appreciably more expensive. If a CUDA application can brute force 700 million MD5s per second, doubling the length is not really going to make it any more secure.
No, I'm not thinking of rainbow tables. The key word here is *single*. As I said before, a salt *does* help against an attacker trying to brute-force multiple passwords from your database, since he can't simply test each brute-force result against all your passwords at once; he has to start all over from scratch for every single password that has a different salt. If he only cares about one *particular* account, the salt doesn't help, no.
But regardless, I apologize for derailing this conversation so far off.
> No, I'm not thinking of rainbow tables. The key word here is > *single*. As I said before, a salt *does* help against an attacker > trying to brute-force multiple passwords from your database, since he > can't simply test each brute-force result against all your passwords > at once; he has to start all over from scratch for every single > password that has a different salt. If he only cares about one > *particular* account, the salt doesn't help, no.
Even in your scenario, it only helps as much as the entropy in the password selection. If everyone has a unique password, it doesn't help at all (admittedly unlikely). Again, it's a linear benefit, but not an exponential one.
I'm not going to get into the arguments about security of the various hashing methods, other than to observe that there have been some fairly misleading statements here.
As far as the proposal goes, I think this is a perfectly reasonable feature request (and you should open a ticket about it if one does not already exist).
I'd favor a solution where your setting mapped the algo name to the actual function used:
Then we could put the existing hash functions (sha1, md5, etc.) in that setting as the default, and get rid of the algo-checking code that currently lives in auth.models. When we do a password comparison, we simply pull the hash name, lookup the function, and away we go.
I don't think this will make it into 1.3, but it's a reasonable thing to do and I think it would help improve all the special-case code that currently lives in auth.models. The patch itself wouldn't be too hard, and I'd be willing to write it myself if nobody else will.
On Sun, Nov 28, 2010 at 3:14 AM, Christophe Pettus <x...@thebuild.com> wrote: > Hi, all,
> Right now, Django's auth system pretty much uses sha1 hardwired in (literally, in the case of User.set_password) for the hash. For a discussion of why a general-purpose hash function is not the best idea in the world for password encryption, see:
> I'd like to propose a backwards-compatible method of allowing different hash algorithms to be used, while not adding new dependencies on external libraries to the core.
> 1. Add a setting DEFAULT_PASSWORD_HASH. This contains the code for the algorithm to use; if it is absent, 'sha1' is assumed.
> 2. Add a setting PASSWORD_HASH_FUNCTIONS. This is a map of algorithm codes to callables; the callable has the same parameters as auth.models.get_hexdigest, and return the hex digest its parameters (to allow for a single function to handle multiple algorithms, the algorithm aprameter to get_hexdigest is retained). For example:
> 3. auth.models.get_hexdigest is modified such that if the algorithm isn't one of the ones it knows about, it consults PASSWORD_HASH_FUNCTIONS and uses the matching function, if present. If there's no match, it fails as it does currently.
> 4. User.set_password() is modified to check the value of DEFAULT_PASSWORD_HASH, and uses that algorithm if specified; otherwise, it uses 'sha1' as it does not. (Optional: Adding the algorithm as a default parameter to User.set_password().)
> Comments?
First comment is that Django already has a pluggable authentication stack, which already allows for this - simply define a new auth backend that tests the password in the manner you wish.
It doesn't allow for this with the default authenticator, but it is doable. I have a django project with >100k users, and none of them have a sha1 hash as their password.
On Tue, Nov 30, 2010 at 4:22 AM, Tom Evans <tevans...@googlemail.com> wrote: > First comment is that Django already has a pluggable authentication > stack, which already allows for this - simply define a new auth > backend that tests the password in the manner you wish.
My understanding of the pluggable authentication system is that it's for situations where you need a totally different authentication mechanism, such as LDAP. Simply replacing the crypto mechanism for the default authentication system should not require developing a lot of pieces. It is something that needs to be upgraded on an ongoing basis for everyone. It's simply best practices.
The federal government already forbids use of SHA-1 after 2010.
> It doesn't allow for this with the default authenticator, but it is > doable. I have a django project with >100k users, and none of them > have a sha1 hash as their password.
I won't comment on the wisdom of this, but I'd not use it as an example of why we don't need to provide flexibility to improve security.
On Wed, Dec 1, 2010 at 2:30 AM, Christopher Petrilli <petri...@amber.org> wrote: > On Tue, Nov 30, 2010 at 4:22 AM, Tom Evans <tevans...@googlemail.com> wrote:
>> First comment is that Django already has a pluggable authentication >> stack, which already allows for this - simply define a new auth >> backend that tests the password in the manner you wish.
> My understanding of the pluggable authentication system is that it's > for situations where you need a totally different authentication > mechanism, such as LDAP. Simply replacing the crypto mechanism for the > default authentication system should not require developing a lot of > pieces. It is something that needs to be upgraded on an ongoing basis > for everyone. It's simply best practices.
It doesn't 'require developing a lot of pieces'. Have you even tried implementing this in the current stack?
At the moment, a typical setup has AUTHENTICATION_BACKENDS set to ('django.contrib.auth.backends.ModelBackend',). Changing how passwords are tested simply requires a different backend, typically derived from ModelBackend, that overrides the authenticate method.
Is that a lot of pieces, or one small one?
> The federal government already forbids use of SHA-1 after 2010.
>> It doesn't allow for this with the default authenticator, but it is >> doable. I have a django project with >100k users, and none of them >> have a sha1 hash as their password.
> I won't comment on the wisdom of this, but I'd not use it as an > example of why we don't need to provide flexibility to improve > security.
> Chris
Wow, that's a thing to say. Your federal government forbids SHA-1, I don't use SHA-1, but you "won't comment on the wisdom of this"? Let's try to keep it civil without casting FUD and aspersions around, eh.
We already have flexibility to implement security in any manner that you can think of. I'm looking for the argument that says 'This current flexibility is not enough, and we need to re-architecture', and I don't think that has been made.
Hi! I'm new to the list and have started to look into authentication. I find that I will need to patch it for my own needs, but would like to ask the opinions of others who are more familiar with the code-base than I am. I apologize if I make any mistakes in the protocol of the list in matters such as including too much code.
where the relevant excerpt is: *March 15, 2006*: The SHA-2 family of hash functions (i.e., SHA-224, SHA-256, SHA-384 and SHA-512) may be used by Federal agencies for all applications using secure hash algorithms. Federal agencies should stop using SHA-1 for digital signatures, digital time stamping and other applications that require collision resistance as soon as practical, and must use the SHA-2 family of hash functions for these applications after 2010. After 2010, Federal agencies may use SHA-1 only for the following applications: hash-based message authentication codes (HMACs); key derivation functions (KDFs); and random number generators (RNGs). Regardless of use, NIST encourages application and protocol designers to use the SHA-2 family of hash functions for all new applications and protocols.
I have also seen discussions in other venues from people who are worried about the security of SHA1 in the event that their system is compromised, can an attacker gain the passwords in the database? The appearance of modules such as django-bcrypt: https://github.com/dwaiter/django-bcrypt/ show that this issue is becoming of more general concern.
Current solutions: 1) Monkey patch: put a top level installed_app that has a listener to the class_prepared signal that performs monkey patching throughout user. This is rather ugly and it feels very fragile to me if the auth module changes internally. 2) Rewrite the Backend as Tom suggests by subclassing ModelBackend: Again, it's not sufficient. Why?
If we look at the Model Backend, we see that yes, the authenticate method currently authenticates against User--but the problem is NOT the authentication per se, but rather that the User class has several methods such as: check_password, set_password, etc. that have encryption hard coded. There are admin commands associated with the User class which refer to methods with a particular encryption method chosen.
3) For users of Django who cannot (say US government agencies, people who have tight security concerns, etc.) use the current module, ignore the auth module and roll their own: This has been attempted before. However, the problem is that it is easy to make mistakes doing this and most of the functionality in the auth module is very good and simply copying most of it to make a few changes to User--and to maintain those against modules which use the user module seems rather excessive.
While my first suggestion was: Move the encryption related portions of the code that are hard coded to the authentication backend. Make a default which follows best practices (I would suggest moving to SHA2 in a backwards compatible fashion) that most people will use. However, for those that want to use bcrypt for example, it would be easy for them to simply write their own backend.
However, there are also merits to Paul's approach of having a mapping in the settings file. What I like about the backend approach is that it allows for graceful fallbacks as function of python version, but gives the user the ability to change the algorithm in a simple way. Also, it saves one from distinguishing between sha1 and sha1 with stretching....Perhaps a compromise would be to have a backend which looks to the settings file for the location of a method?
But, if I write a patch that works and maintains backwards compatibility would it be accepted? Is it better to email it here, or to submit a ticket, claim the ticket, and then add the patch?
william.ratcl...@gmail.com> wrote: > Hi! I'm new to the list and have started to look into authentication. I > find that I will need to patch it for my own needs, but would like to ask > the opinions of others who are more familiar with the code-base than I am. > I apologize if I make any mistakes in the protocol of the list in matters > such as including too much code.
> SHA1 is not secure. This is not a nationalism issue. For example:
> where the relevant excerpt is: > *March 15, 2006*: The SHA-2 family of hash functions (i.e., SHA-224, > SHA-256, SHA-384 and SHA-512) may be used by Federal agencies for all > applications using secure hash algorithms. Federal agencies should stop > using SHA-1 for digital signatures, digital time stamping and other > applications that require collision resistance as soon as practical, and > must use the SHA-2 family of hash functions for these applications after > 2010. After 2010, Federal agencies may use SHA-1 only for the following > applications: hash-based message authentication codes (HMACs); key > derivation functions (KDFs); and random number generators (RNGs). Regardless > of use, NIST encourages application and protocol designers to use the SHA-2 > family of hash functions for all new applications and protocols.
> I have also seen discussions in other venues from people who are worried > about the security of SHA1 in the event that their system is compromised, > can an attacker gain the passwords in the database? The appearance of > modules such as django-bcrypt: > https://github.com/dwaiter/django-bcrypt/ > show that this issue is becoming of more general concern.
> Current solutions: > 1) Monkey patch: > put a top level installed_app that has a listener to the class_prepared > signal that performs monkey patching throughout user. > This is rather ugly and it feels very fragile to me if the auth module > changes internally. > 2) Rewrite the Backend as Tom suggests by subclassing ModelBackend: > Again, it's not sufficient. Why?
> If we look at the Model Backend, we see that yes, the authenticate method > currently authenticates against User--but the problem is NOT the > authentication per se, but rather that the User class has several methods > such as: > check_password, set_password, etc. that have encryption hard coded. There > are admin commands associated with the User class which refer to methods > with a particular encryption method chosen.
> 3) For users of Django who cannot (say US government agencies, people who > have tight security concerns, etc.) use the current module, ignore the auth > module and roll their own: > This has been attempted before. However, the problem is that it is easy to > make mistakes doing this and most of the functionality in the auth module is > very good and simply copying most of it to make a few changes to User--and > to maintain those against modules which use the user module seems rather > excessive.
> While my first suggestion was: > Move the encryption related portions of the code that are hard coded to the > authentication backend. Make a default which follows best practices (I > would suggest moving to SHA2 in a backwards compatible fashion) that most > people will use. However, for those that want to use bcrypt for example, it > would be easy for them to simply write their own backend.
> However, there are also merits to Paul's approach of having a mapping in > the settings file. What I like about the backend approach is that it > allows for graceful fallbacks as function of python version, but gives the > user the ability to change the algorithm in a simple way. > Also, it saves one from distinguishing between sha1 and sha1 with > stretching....Perhaps a compromise would be to have a backend > which looks to the settings file for the location of a method?
> But, if I write a patch that works and maintains backwards compatibility > would it be accepted? Is it better to email it here, or to submit a ticket, > claim the ticket, and then add the patch?
> -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-developers@googlegroups.com. > To unsubscribe from this group, send email to > django-developers+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en.
That's a subject which comes up every few months, sadly.
In a nutshell, if something requires python >= 2.5 or a lib for older versions of Python, forget about adding it.
See f. e. http://code.djangoproject.com/ticket/5600 which was closed as a no-fix 3 years ago (full disclosure: I'm coh in that bug report). There was also a discussion on this mailing list a few weeks ago about increasing the salt length, but afaik it had no code-change as a result.
I apologize if I sound a bit grumpy, but I've spend the last 5 days with monkey-patching a local branch of the auth lib up to the latest in security (SHA512, 128-bit salt, pre-stretching, pbkdf2, stronger random token generation (salt, csrf, default-password)), now it spreads into other areas of the django-lib as well (currently SECRET_KEY in the starproject script).
Of course I would very much welcome such a proposal, yet I just believe the odds for it to happen are (very) low.
> Hi! I'm new to the list and have started to look into authentication. > I find that I will need to patch it for my own needs, but would like > to ask the opinions of others who are more familiar with the code-base > than I am. I apologize if I make any mistakes in the protocol of the > list in matters such as including too much code.
the idea of a salt is only to make certain that two users who happen to use the same password (123456, anyone?) don't end up with the same hash in order to make a pre-computation (password lists or rainbow tables) infeasible. yet given the short salts in django, it's not really unlikely that two users will not share the same salt as well as password. Also keep in mind that, due to the Birthday Paradoxon, a hash with N bits only has odds of 1:2^(N/2) instead of 1:2^N for a collision to occur.
Hope that clears up things a little bit :)
coh
On 02/11/2011 02:10 PM, Eduardo Cereto Carvalho wrote: > I'm not an expert on the subject. > > But I think that the hashes security issues are olved by the use of a > "salt", salted hashes are known to be a very secure way to store data.
Hi! The scenario that I am considering is when the attacker has your database--can they compromise the passwords in it? While I believe that a salt will protect you against a "Rainbow Table" attack, I'm not convinced that it will protect you against the brute-force attacks which are now possible. I will try to consult some experts today and see if they are willing to go on record.
William
On Fri, Feb 11, 2011 at 8:10 AM, Eduardo Cereto Carvalho <
eduardocer...@gmail.com> wrote: > I'm not an expert on the subject.
> But I think that the hashes security issues are olved by the use of a > "salt", salted hashes are known to be a very secure way to store data.
> On Fri, Feb 11, 2011 at 3:59 AM, William Ratcliff < > william.ratcl...@gmail.com> wrote:
>> Hi! I'm new to the list and have started to look into authentication. I >> find that I will need to patch it for my own needs, but would like to ask >> the opinions of others who are more familiar with the code-base than I am. >> I apologize if I make any mistakes in the protocol of the list in matters >> such as including too much code.
>> SHA1 is not secure. This is not a nationalism issue. For example:
>> where the relevant excerpt is: >> *March 15, 2006*: The SHA-2 family of hash functions (i.e., SHA-224, >> SHA-256, SHA-384 and SHA-512) may be used by Federal agencies for all >> applications using secure hash algorithms. Federal agencies should stop >> using SHA-1 for digital signatures, digital time stamping and other >> applications that require collision resistance as soon as practical, and >> must use the SHA-2 family of hash functions for these applications after >> 2010. After 2010, Federal agencies may use SHA-1 only for the following >> applications: hash-based message authentication codes (HMACs); key >> derivation functions (KDFs); and random number generators (RNGs). Regardless >> of use, NIST encourages application and protocol designers to use the SHA-2 >> family of hash functions for all new applications and protocols.
>> I have also seen discussions in other venues from people who are worried >> about the security of SHA1 in the event that their system is compromised, >> can an attacker gain the passwords in the database? The appearance of >> modules such as django-bcrypt: >> https://github.com/dwaiter/django-bcrypt/ >> show that this issue is becoming of more general concern.
>> Current solutions: >> 1) Monkey patch: >> put a top level installed_app that has a listener to the class_prepared >> signal that performs monkey patching throughout user. >> This is rather ugly and it feels very fragile to me if the auth module >> changes internally. >> 2) Rewrite the Backend as Tom suggests by subclassing ModelBackend: >> Again, it's not sufficient. Why?
>> If we look at the Model Backend, we see that yes, the authenticate method >> currently authenticates against User--but the problem is NOT the >> authentication per se, but rather that the User class has several methods >> such as: >> check_password, set_password, etc. that have encryption hard coded. >> There are admin commands associated with the User class which refer to >> methods with a particular encryption method chosen.
>> 3) For users of Django who cannot (say US government agencies, people who >> have tight security concerns, etc.) use the current module, ignore the auth >> module and roll their own: >> This has been attempted before. However, the problem is that it is easy >> to make mistakes doing this and most of the functionality in the auth module >> is very good and simply copying most of it to make a few changes to >> User--and to maintain those against modules which use the user module seems >> rather excessive.
>> While my first suggestion was: >> Move the encryption related portions of the code that are hard coded to >> the authentication backend. Make a default which follows best practices (I >> would suggest moving to SHA2 in a backwards compatible fashion) that most >> people will use. However, for those that want to use bcrypt for example, it >> would be easy for them to simply write their own backend.
>> However, there are also merits to Paul's approach of having a mapping in >> the settings file. What I like about the backend approach is that it >> allows for graceful fallbacks as function of python version, but gives the >> user the ability to change the algorithm in a simple way. >> Also, it saves one from distinguishing between sha1 and sha1 with >> stretching....Perhaps a compromise would be to have a backend >> which looks to the settings file for the location of a method?
>> But, if I write a patch that works and maintains backwards compatibility >> would it be accepted? Is it better to email it here, or to submit a ticket, >> claim the ticket, and then add the patch?
>> -- >> You received this message because you are subscribed to the Google Groups >> "Django developers" group. >> To post to this group, send email to django-developers@googlegroups.com. >> To unsubscribe from this group, send email to >> django-developers+unsubscribe@googlegroups.com. >> For more options, visit this group at >> http://groups.google.com/group/django-developers?hl=en.
> -- > Eduardo Cereto Carvalho
> -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-developers@googlegroups.com. > To unsubscribe from this group, send email to > django-developers+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en.
On Friday, 11 February 2011 at 10:50 PM, Clemens-O. Hoppe wrote:
That's a subject which comes up every few months, sadly.
> In a nutshell, if something requires python >= 2.5 or a lib for older > versions of Python, forget about adding it.
That's not true at all.
If an idea is important enough, we will include compatibility options for older Python versions. For example, we ship copies of unittest2, dictconfig logging, and a number of importlib and fuctional programming utilities in order to support the Python versions in which those facilities aren't available natively.
Of course, we will balance the value of a change against the cost of maintaining a local copy of that library, but to say that we won't do this at all is patently and demonstrably incorrect.
I'm not an expert, but that's correct. A too-fast or broken hash function will still be "vulnerable" to a brute force attack [1]. Salting doesn't prevent this.
> Hi! The scenario that I am considering is when the attacker has your > database--can they compromise the passwords in it? While I believe that a > salt will protect you against a "Rainbow Table" attack, I'm not convinced that > it will protect you against the brute-force attacks which are now possible. I > will try to consult some experts today and see if they are willing to go on > record.
> William
> On Fri, Feb 11, 2011 at 8:10 AM, Eduardo Cereto Carvalho > <eduardocer...@gmail.com> wrote: >> I'm not an expert on the subject.
>> But I think that the hashes security issues are olved by the use of a "salt", >> salted hashes are known to be a very secure way to store data.
>> On Fri, Feb 11, 2011 at 3:59 AM, William Ratcliff >> <william.ratcl...@gmail.com> wrote: >>> Hi! I'm new to the list and have started to look into authentication. I >>> find that I will need to patch it for my own needs, but would like to ask >>> the opinions of others who are more familiar with the code-base than I am. >>> I apologize if I make any mistakes in the protocol of the list in matters >>> such as including too much code.
>>> where the relevant excerpt is: >>> March 15, 2006: The SHA-2 family of hash functions (i.e., SHA-224, SHA-256, >>> SHA-384 and SHA-512) may be used by Federal agencies for all applications >>> using secure hash algorithms. Federal agencies should stop using SHA-1 for >>> digital signatures, digital time stamping and other applications that >>> require collision resistance as soon as practical, and must use the SHA-2 >>> family of hash functions for these applications after 2010. After 2010, >>> Federal agencies may use SHA-1 only for the following applications: >>> hash-based message authentication codes (HMACs); key derivation functions >>> (KDFs); and random number generators (RNGs). Regardless of use, NIST >>> encourages application and protocol designers to use the SHA-2 family of >>> hash functions for all new applications and protocols.
>>> I have also seen discussions in other venues from people who are worried >>> about the security of SHA1 in the event that their system is compromised, >>> can an attacker gain the passwords in the database? The appearance of >>> modules such as django-bcrypt: >>> https://github.com/dwaiter/django-bcrypt/ >>> show that this issue is becoming of more general concern.
>>> Current solutions: >>> 1) Monkey patch: >>> put a top level installed_app that has a listener to the class_prepared >>> signal that performs monkey patching throughout user. >>> This is rather ugly and it feels very fragile to me if the auth module >>> changes internally. >>> 2) Rewrite the Backend as Tom suggests by subclassing ModelBackend: >>> Again, it's not sufficient. Why?
>>> If we look at the Model Backend, we see that yes, the authenticate method >>> currently authenticates against User--but the problem is NOT the >>> authentication per se, but rather that the User class has several methods >>> such as: >>> check_password, set_password, etc. that have encryption hard coded. There >>> are admin commands associated with the User class which refer to methods >>> with a particular encryption method chosen.
>>> 3) For users of Django who cannot (say US government agencies, people who >>> have tight security concerns, etc.) use the current module, ignore the auth >>> module and roll their own: >>> This has been attempted before. However, the problem is that it is easy to >>> make mistakes doing this and most of the functionality in the auth module is >>> very good and simply copying most of it to make a few changes to User--and >>> to maintain those against modules which use the user module seems rather >>> excessive.
>>> While my first suggestion was: >>> Move the encryption related portions of the code that are hard coded to the >>> authentication backend. Make a default which follows best practices (I >>> would suggest moving to SHA2 in a backwards compatible fashion) that most >>> people will use. However, for those that want to use bcrypt for example, it >>> would be easy for them to simply write their own backend.
>>> However, there are also merits to Paul's approach of having a mapping in the >>> settings file. What I like about the backend approach is that it allows >>> for graceful fallbacks as function of python version, but gives the user the >>> ability to change the algorithm in a simple way. >>> Also, it saves one from distinguishing between sha1 and sha1 with >>> stretching....Perhaps a compromise would be to have a backend >>> which looks to the settings file for the location of a method?
>>> But, if I write a patch that works and maintains backwards compatibility >>> would it be accepted? Is it better to email it here, or to submit a ticket, >>> claim the ticket, and then add the patch?
To quote the issue 5600: So I think the only thing we can do here is increase the salt size. I think anyone who feels they need more security will have to implement a custom authentication backend; building this into Django is just to fraught with danger.
Yet the patch for the salt-size only increase, it was added not 24 hours after that, still didn't make its way into any release as far as I'm aware of it.
Given the current 20-bit length (5 hex chars), salt-collisions will happen.
On 02/11/2011 04:04 PM, Russell Keith-Magee wrote:
> If an idea is important enough, we will include compatibility options > for older Python versions. >> In a nutshell, if something requires python >= 2.5 or a lib for older >> versions of Python, forget about adding it. > That's not true at all. > ... but to say that we won't do > this at all is patently and demonstrably incorrect.
Sorry if it came along as too harsh --
> I apologize if I sound a bit grumpy, but I've spend the last 5 days with
> monkey-patching a local branch of the auth lib...
Once again, I didn't mean to insult any dev (running a few projects myself, so I know how much work it is) and I appreciate the work that is done.
I agree, it seems like a lot of work for individual developers to be
patching django themselves for secure auth. I'd be extremely grateful
to see this merged into the core.
<clemens.o.ho...@googlemail.com> wrote:
> To quote the issue 5600:
> So I think the only thing we can do here is increase the salt size.
> I think anyone who feels they need more security will have to implement a
> custom authentication backend; building this into Django is just to
> fraught with danger.
> Yet the patch for the salt-size only increase, it was added not 24 hours
> after that, still didn't make its way into any release as far as I'm
> aware of it.
> Given the current 20-bit length (5 hex chars), salt-collisions will happen.
> On 02/11/2011 04:04 PM, Russell Keith-Magee wrote:
> > If an idea is important enough, we will include compatibility options
> > for older Python versions.
> >> In a nutshell, if something requires python >= 2.5 or a lib for older
> >> versions of Python, forget about adding it.
> > That's not true at all.
> > ... but to say that we won't do
> > this at all is patently and demonstrably incorrect.
> Sorry if it came along as too harsh --
> > I apologize if I sound a bit grumpy, but I've spend the last 5 days with
> > monkey-patching a local branch of the auth lib...
> Once again, I didn't mean to insult any dev (running a few projects
> myself, so I know how much work it is) and I appreciate the work that is
> done.
clemens.o.ho...@googlemail.com> wrote: > That's a subject which comes up every few months, sadly.
> In a nutshell, if something requires python >= 2.5 or a lib for older > versions of Python, forget about adding it.
> See f. e. http://code.djangoproject.com/ticket/5600 which was closed as a > no-fix 3 years ago (full disclosure: I'm coh in that bug report). There was > also a discussion on this mailing list a few weeks ago about increasing the > salt length, but afaik it had no code-change as a result.
> I apologize if I sound a bit grumpy, but I've spend the last 5 days with > monkey-patching a local branch of the auth lib up to the latest in security > (SHA512, 128-bit salt, pre-stretching, pbkdf2, stronger random token > generation (salt, csrf, default-password)), now it spreads into other areas > of the django-lib as well (currently SECRET_KEY in the starproject script).
> Of course I would very much welcome such a proposal, yet I just believe the > odds for it to happen are (very) low.
> Cheers,
> coh
> On 02/11/2011 06:59 AM, William Ratcliff wrote:
> Hi! I'm new to the list and have started to look into authentication. I >> find that I will need to patch it for my own needs, but would like to ask >> the opinions of others who are more familiar with the code-base than I am. >> I apologize if I make any mistakes in the protocol of the list in matters >> such as including too much code.
>> SHA1 is not secure. This is not a nationalism issue. For example:
> -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-developers@googlegroups.com. > To unsubscribe from this group, send email to > django-developers+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en.
Wasn't, but now is -- https://bitbucket.org/coh/django_sec_mod/ . It's against svn rev 15488. Please note that any sort of backwards compat is broken with on purpose and I haven't really tested the changes yet.
As for the salt length, I was actually referring to ticket 5600.