You're right. I get kinda pissed when people call me "dammed irresponsible" because I can't find the time to solve some technical problems. It implies a sense of entitlement to my time that rubs me the wrong way.
You did exactly the right thing: figured out how to solve the problem regardless. That's something that'll motivate me; calling me stupid or irresponsible won't.
So yeah, you're right, it is bullshit, and so is the attitude I responded to. Garbage in, garbage out, I suppose.
Having several open source projects of my own, and contributing to a few more, I definitely know how you feel.
Here's what I want to know about this in a nutshell:
Does Django (the project as a whole) want to provide the best possible security, within reason, for its contrib.auth module?
If not, why not, and why isn't it stated prominently in the documentation?
Is bcrypt not the best possible security, or reasonably close to it?
If not, why not? I'm not even remotely close to a cryptography expert, so although bcrypt's support for arbitrary work factors seems to provide very good security to me I know I could very well be horribly wrong in this thinking.
Is providing bcrypt hashing for passwords in contrib.auth not within the realm of reasonable effort? This could mean rewriting bcrypt in pure Python and including it in contrib, to support Windows users.
If not, why not? Perhaps rewriting bcrypt in Pure Python is not easy -- I haven't tried it myself.
If bcrypt hashing is secure and reasonable to implement, and Django wants to provide the best security possible (within reason), why is this not a blocking issue for Django 1.3?
I genuinely don't know the answers to any of these questions, so I'd really love to know.
> I genuinely don't know the answers to any of these questions, so I'd really love to know.
Well, I don't speak for the project as a whole, so I'm going to just answer personally. I'll try to channel the rest of the core team as best I can, but please don't take any of the below as any sort of "official" thing. I may very well have a different point of view or be in the minority -- I often am, actually.
> Does Django (the project as a whole) want to provide the best possible security, within reason, for its contrib.auth module?
I certainly do, and I'm sure the rest of the team feels similarly. We take security issues very seriously and I'm disappointed we've not been able to demonstrate that through our past actions (i.e. built-in XSS and CSRF protection, our security releases, etc.) This indicates to me that we haven't done a good job being clear about our goals with regard to security. So that's something to work on.
I think, though, that reasonable people can -- and do -- disagree about what "within reason" means. I mean, are we building Django to protect against script kiddies? Malicious employees? Corporate espionage? Government agencies?
Me, I suspect I'd choose to fold in the face of a lawsuit or subpoena, so I don't particularly care if my passwords are safe against the NSA or something. But that's because I'm a spoiled comfortable middle class yutz.
> Is bcrypt not the best possible security, or reasonably close to it?
Personally I have no idea. I'm not a security expert, nor am I even a well-informed amateur. I've read (here and on Reddit, mostly) that bcrypt is the best there is. I've read that bcrypt is for lamers and scrypt is better. I've also been told that salts & sha1 is fine. I've also been told that sha1 will eat my children and burn my house down. I'm honestly not qualified to judge.
Given what I know, my feeling is that bcrypt/scrypt is certainly an improvement over sha1, and probably an improvement over any sha version. I'm not convinced that it's an improvement over, say, multiple rounds of a sha algorithm.
More importantly, I'm not clear on exactly how big a deal this is. There's a spectrum: at one end, we activate our security policy, halt everything, and release new versions, damned the backwards compatibility concerns. At the other end of the spectrum we do nothing. I really don't know where on this spectrum the issue falls. I suspect that it's somewhere a bit more serious than the potential timing attacks we just fixed in trunk, but maybe a bit less serious than the DOS attack our last security release fixed.
> Is providing bcrypt hashing for passwords in contrib.auth not within the realm of reasonable effort? This could mean rewriting bcrypt in pure Python and including it in contrib, to support Windows users.
Of course it's possible, but the devil as they say is in the details. I think it should be possible to support bcrypt if it's installed, but the concerns about data portability need to be addressed in some way. At the very least there should be some "I don't care about data portability" flag you can set to turn on bcrupt support.
A pure-Python bcrypt implementation would certainly help. But I certainly am not going to rewrite bcrypt -- I know enough about crypto to know that I shouldn't be allowed with a thousand miles of writing an algorithm by hand. And frankly there aren't any active committers I'd trust to write such an implementation. It would have to come from a pretty unimpeachable source, wouldn't you agree?
> If bcrypt hashing is secure and reasonable to implement, and Django wants to provide the best security possible (within reason), why is this not a blocking issue for Django 1.3?
Because nobody proposed it and we're well past feature freeze for 1.3 and very close to cutting a release candidate. Also because there's a great third-party app that provides this feature in a very easy-to-use way :)
But If a majority of the community wanted to make bcrypt (or whatever) a blocking feature for 1.3 then I'd go along with it. I'd argue against it, but again I'm just one voice. A loud one, maybe, but I'd like to think I can take being wrong graciously. I was against template auto-escaping originally, for example, so clearly I'e already got a good track record of being wrong about security.
I hope that helps; it's late and I've had a long day. Please ask if I'm not being clear.
I think, though, that reasonable people can -- and do -- disagree about what "within reason" means.
Absolutely, which is where my next questions come from.
I'm not convinced that it's an improvement over, say, multiple rounds of a sha algorithm.
Sure, for this conversation feel free to replace "bcrypt" with "configurable rounds of SHA1".
More importantly, I'm not clear on exactly how big a deal this is.
I agree here.
Yes, bcrypt is better.
Is it "better enough" to warrant backwards-incompatible changes? Maybe not.
I'm not clear on Django's database-compatibility policy though. Are databases created with Django 1.X guaranteed to work with Django 1.Y (where Y < X)? If not, then there are no problems. If so, then you're right, a backwards incompatible change like this is not trivial.
Maybe I completely missed this in the docs.
At the very least there should be some "I don't care about data portability" flag you can set to turn on bcrupt support.
This goes back to my question about databases working with older versions of Django. Did I miss an important part of the docs?
A pure-Python bcrypt implementation would certainly help. But I certainly am not going to rewrite bcrypt -- I know enough about crypto to know that I shouldn't be allowed with a thousand miles of writing an algorithm by hand. And frankly there aren't any active committers I'd trust to write such an implementation. It would have to come from a pretty unimpeachable source, wouldn't you agree?
This is the first argument that really convinces me. If you need to support Windows and don't have anyone you trust to write a real crypt implementation in pure Python, that kind of kills the idea in its tracks.
A third-party app usable by non-Windows-users seems like the best option.
I hope that helps; it's late and I've had a long day. Please ask if I'm not being clear.
Having several open source projects of my own, and contributing to a few more, I'd like to say that I don't think you're on the right track if you're trying to get a real response with your questions here; you're basically doing the "so, have you stopped beating your wife yet" routine.
Don't believe me? Your words:
Does Django (the project as a whole) want to provide the best possible security, within reason, for its contrib.auth module?
If not, why not, and why isn't it stated prominently in the documentation?
Of course we want to provide the best possible security, within reason. But reasonable people can and do disagree on what's "within reason", and Jacob's outlined some technical hurdles regarding bcrypt which -- so far as I'm aware -- no-one in this thread has bothered to offer solutions for.
If you're genuinely interested in seeing bcrypt in Django, and have constructive suggestions on how to overcome these technical hurdles, then I'm all ears. If, on the other hand, you're just going to post passive-aggressive stuff framed to make us look like we don't really care about security, well, don't expect me or anyone else to fall all over themselves trying to help you out.
Mmm, that's not how I read Steve's questions -- I took them as honest questions about from someone who doesn't really follow the project and isn't sure where our priorities lie. We have to keep in mind that at this point a bulk of our users don't keep close track of the development process and priorities. Heck, even I have trouble keeping up some times.
At best I can say it's incredibly poorly phrased if it was trying to raise constructive points. The implication of "if you really cared about security, you'd..." just rubs me the wrong way.
I'm sorry. I'm a programmer and think in terms of `if X elif Y else Z` statements.
I admitted I might be wrong at pretty much any stage, and Jacob's response convinced me that my "rewrite bcrypt in Python" option is probably not reasonable at this point.
How could I have phrased that differently and still asked the same questions?
"We estimate that on modern (2009) hardware, if 5 seconds are spent computing a derived key, the cost of a hardware brute-force attack against scrypt is roughly 4000 times greater than the cost of a similar attack against bcrypt (to find the same password), and 20000 times greater than a similar attack against PBKDF2."
Well, yes and no. scrypt is a very sensible design based on the battle-tested PBKDF2, but it's still a lot newer than bcrypt. That said, either algorithm should be totally fine.
I don't submit patches to Django because I: 1) am not a Django dev. 2) Don't use it. 3) believe it is the job of the people who do both of those to do it.
I don't normally have this sort of attitude, but when it comes to security, "if you can't [be bothered to] do it right, DON'T." MD5/SHA/etc are designed to be fast. That is the absolute last thing you want in a hashing algorithm that you're using for passwords.
Comments
> It's just damned irresponsible.
Since you feel that strongly I can expect to see a patch from you fixing the technical issues I mentioned, right? You write it, I'll commit it. Go.
Look, I love Django, but to be fair this is kind of a bullshit response.
There are things I hate about Git, and I could fix them myself, but I don't submit patches to Git. I just use Mercurial instead.
"Send patches" isn't a be-all, end-all response to any criticism of an open source project.
You're right. I get kinda pissed when people call me "dammed irresponsible" because I can't find the time to solve some technical problems. It implies a sense of entitlement to my time that rubs me the wrong way.
You did exactly the right thing: figured out how to solve the problem regardless. That's something that'll motivate me; calling me stupid or irresponsible won't.
So yeah, you're right, it is bullshit, and so is the attitude I responded to. Garbage in, garbage out, I suppose.
Having several open source projects of my own, and contributing to a few more, I definitely know how you feel.
Here's what I want to know about this in a nutshell:
Does Django (the project as a whole) want to provide the best possible security, within reason, for its contrib.auth module?
If not, why not, and why isn't it stated prominently in the documentation?
Is bcrypt not the best possible security, or reasonably close to it?
If not, why not? I'm not even remotely close to a cryptography expert, so although bcrypt's support for arbitrary work factors seems to provide very good security to me I know I could very well be horribly wrong in this thinking.
Is providing bcrypt hashing for passwords in contrib.auth not within the realm of reasonable effort? This could mean rewriting bcrypt in pure Python and including it in contrib, to support Windows users.
If not, why not? Perhaps rewriting bcrypt in Pure Python is not easy -- I haven't tried it myself.
If bcrypt hashing is secure and reasonable to implement, and Django wants to provide the best security possible (within reason), why is this not a blocking issue for Django 1.3?
I genuinely don't know the answers to any of these questions, so I'd really love to know.
> I genuinely don't know the answers to any of these questions, so I'd really love to know.
Well, I don't speak for the project as a whole, so I'm going to just answer personally. I'll try to channel the rest of the core team as best I can, but please don't take any of the below as any sort of "official" thing. I may very well have a different point of view or be in the minority -- I often am, actually.
> Does Django (the project as a whole) want to provide the best possible security, within reason, for its contrib.auth module?
I certainly do, and I'm sure the rest of the team feels similarly. We take security issues very seriously and I'm disappointed we've not been able to demonstrate that through our past actions (i.e. built-in XSS and CSRF protection, our security releases, etc.) This indicates to me that we haven't done a good job being clear about our goals with regard to security. So that's something to work on.
I think, though, that reasonable people can -- and do -- disagree about what "within reason" means. I mean, are we building Django to protect against script kiddies? Malicious employees? Corporate espionage? Government agencies?
Me, I suspect I'd choose to fold in the face of a lawsuit or subpoena, so I don't particularly care if my passwords are safe against the NSA or something. But that's because I'm a spoiled comfortable middle class yutz.
> Is bcrypt not the best possible security, or reasonably close to it?
Personally I have no idea. I'm not a security expert, nor am I even a well-informed amateur. I've read (here and on Reddit, mostly) that bcrypt is the best there is. I've read that bcrypt is for lamers and scrypt is better. I've also been told that salts & sha1 is fine. I've also been told that sha1 will eat my children and burn my house down. I'm honestly not qualified to judge.
Given what I know, my feeling is that bcrypt/scrypt is certainly an improvement over sha1, and probably an improvement over any sha version. I'm not convinced that it's an improvement over, say, multiple rounds of a sha algorithm.
More importantly, I'm not clear on exactly how big a deal this is. There's a spectrum: at one end, we activate our security policy, halt everything, and release new versions, damned the backwards compatibility concerns. At the other end of the spectrum we do nothing. I really don't know where on this spectrum the issue falls. I suspect that it's somewhere a bit more serious than the potential timing attacks we just fixed in trunk, but maybe a bit less serious than the DOS attack our last security release fixed.
> Is providing bcrypt hashing for passwords in contrib.auth not within the realm of reasonable effort? This could mean rewriting bcrypt in pure Python and including it in contrib, to support Windows users.
Of course it's possible, but the devil as they say is in the details. I think it should be possible to support bcrypt if it's installed, but the concerns about data portability need to be addressed in some way. At the very least there should be some "I don't care about data portability" flag you can set to turn on bcrupt support.
A pure-Python bcrypt implementation would certainly help. But I certainly am not going to rewrite bcrypt -- I know enough about crypto to know that I shouldn't be allowed with a thousand miles of writing an algorithm by hand. And frankly there aren't any active committers I'd trust to write such an implementation. It would have to come from a pretty unimpeachable source, wouldn't you agree?
> If bcrypt hashing is secure and reasonable to implement, and Django wants to provide the best security possible (within reason), why is this not a blocking issue for Django 1.3?
Because nobody proposed it and we're well past feature freeze for 1.3 and very close to cutting a release candidate. Also because there's a great third-party app that provides this feature in a very easy-to-use way :)
But If a majority of the community wanted to make bcrypt (or whatever) a blocking feature for 1.3 then I'd go along with it. I'd argue against it, but again I'm just one voice. A loud one, maybe, but I'd like to think I can take being wrong graciously. I was against template auto-escaping originally, for example, so clearly I'e already got a good track record of being wrong about security.
I hope that helps; it's late and I've had a long day. Please ask if I'm not being clear.
Yes, bcrypt is better.
Is it "better enough" to warrant backwards-incompatible changes? Maybe not.
I'm not clear on Django's database-compatibility policy though. Are databases created with Django 1.X guaranteed to work with Django 1.Y (where Y < X)? If not, then there are no problems. If so, then you're right, a backwards incompatible change like this is not trivial.
Maybe I completely missed this in the docs.
This goes back to my question about databases working with older versions of Django. Did I miss an important part of the docs? This is the first argument that really convinces me. If you need to support Windows and don't have anyone you trust to write a real crypt implementation in pure Python, that kind of kills the idea in its tracks.A third-party app usable by non-Windows-users seems like the best option.
Definitely. Thanks for taking the time to answer.Having several open source projects of my own, and contributing to a few more, I'd like to say that I don't think you're on the right track if you're trying to get a real response with your questions here; you're basically doing the "so, have you stopped beating your wife yet" routine.
Don't believe me? Your words:
Does Django (the project as a whole) want to provide the best possible security, within reason, for its contrib.auth module? If not, why not, and why isn't it stated prominently in the documentation?
Of course we want to provide the best possible security, within reason. But reasonable people can and do disagree on what's "within reason", and Jacob's outlined some technical hurdles regarding bcrypt which -- so far as I'm aware -- no-one in this thread has bothered to offer solutions for.
If you're genuinely interested in seeing bcrypt in Django, and have constructive suggestions on how to overcome these technical hurdles, then I'm all ears. If, on the other hand, you're just going to post passive-aggressive stuff framed to make us look like we don't really care about security, well, don't expect me or anyone else to fall all over themselves trying to help you out.
Mmm, that's not how I read Steve's questions -- I took them as honest questions about from someone who doesn't really follow the project and isn't sure where our priorities lie. We have to keep in mind that at this point a bulk of our users don't keep close track of the development process and priorities. Heck, even I have trouble keeping up some times.
At best I can say it's incredibly poorly phrased if it was trying to raise constructive points. The implication of "if you really cared about security, you'd..." just rubs me the wrong way.
I'm sorry. I'm a programmer and think in terms of `if X elif Y else Z` statements.
I admitted I might be wrong at pretty much any stage, and Jacob's response convinced me that my "rewrite bcrypt in Python" option is probably not reasonable at this point.
How could I have phrased that differently and still asked the same questions?
> Is bcrypt not the best possible security, or reasonably close to it?
Reasonably close to it, yes, but scrypt is better. scrypt makes the KDF expensive not just in time, but in memory as well.
http://www.tarsnap.com/scrypt.html
"We estimate that on modern (2009) hardware, if 5 seconds are spent computing a derived key, the cost of a hardware brute-force attack against scrypt is roughly 4000 times greater than the cost of a similar attack against bcrypt (to find the same password), and 20000 times greater than a similar attack against PBKDF2."
Well, yes and no. scrypt is a very sensible design based on the battle-tested PBKDF2, but it's still a lot newer than bcrypt. That said, either algorithm should be totally fine.
I don't submit patches to Django because I: 1) am not a Django dev. 2) Don't use it. 3) believe it is the job of the people who do both of those to do it.
I don't normally have this sort of attitude, but when it comes to security, "if you can't [be bothered to] do it right, DON'T." MD5/SHA/etc are designed to be fast. That is the absolute last thing you want in a hashing algorithm that you're using for passwords.