Amazon WS Crypto Sigs v2 Broken (Even Amazon Can't Get Crypto Right)
rdist.root.org
rdist.root.org
What you call "disingenuous", I call a "more complete consideration of the AWS security system". Even though I think you're aware of Nate's background, I'll assume good faith and just remind you that when you're reviewing protocols professionally, things like "messages are replayable and the protocol is only secure when run over TLS" get called out.
Hmm, good point. The AWS documentation has never been very explicit about these sorts of issues -- I'll email a few people at Amazon and suggest that they improve this.
With the exception of identity, SSL provides all the integrity protection, ordering, uniqueness, and even privacy that a developer could want. If you're willing to use client certs or SRP or basic auth, then you have identity covered too.
Amazon is exactly right in recommending SSL primarily. I just think they should stop there and not add "but if you have SSL performance problems, use AWS-Auth".
If you're crazy enough to be issuing PUTs with different data, or PUTs and DELETEs, to the same object name within the time window before the request expires (yes, S3 checks the date/time for validity), an attacker could reorder your operations... but that's not actually a security flaw, since S3 itself is allowed to reorder operations (cf "eventual consistency"). All an attacker would be able to do in that case is break code which is already broken.
As long as S3 remains connected, it should reach consistency immediately (for PUTing an object which doesn't exist yet) or within a few seconds (for PUTing a new version of an object which already exists or DELETEing an object). But there is currently no way to determine if S3 is connected, so you can't rely on the "typical" consistency window.
BTW, you can specify how much clock skew S3 should permit when you construct your requests.
So... are you sure you want to try to build crypto into your application
Yes, I am. :-)
BTW, what do I need to do in order to convince you to start recommending scrypt instead of bcrypt?
I think the lower layer should handle uniqueness, ordering, etc. in addition to integrity protection. As I said in the blog comments, "At some point in the past, I said the following" is not all that is needed for a secure protocol. If ensuring this kind of property is left to the caller, the chance for implementation mistakes would be much higher.
The problem is, a lot of the recent issues that have been identified have come from people who are probably qualified to write the training courses, and yet they still make mistakes. For example, OpenID still had a hole, even though it's been debated ad nauseum for years on mailing lists around the world by some of the top people in the field. This isn't like building a bridge where you just follow some well understood design principles and the bridge doesn't fall down. We probably just have to admit that this problem is hard (really hard) and there's no amount of rote learning, training or certification that prepares you for the inventiveness and creativity of the people who want to hack your system. The best solution seems to be complete transparency, eternal vigilance, maximum communication and shared experience.
edit: I'm not saying training isn't important for anyone doing this stuff - just that making it mandatory probably won't change much over what we have now.
I had the (mis)fortune of having to implement something similar and it took me quite awhile to make sure it was correct in both design and implementation. Do you want to run cryptographic tests for randomness? Do you know how? If not, stay away.
I really agree with tptacek, avoid implementing crypto like the plague.
Becoming a cryptography expert these days is not easy, there is much to learn.
If you find yourself needing to implement crypto, it's likely you can avoid it by thinking about the situation differently. For example, many web developers get seduced into designing their own crypto as a way to push state to the client instead of managing it on the server. This opens up a much wider attack surface on the server application since now every part of that blob needs to be considered malicious. As the saying goes, "... now you have two problems."
The reason all this is so hard is that crypto is fundamentally unsafe. People hear that crypto is strong and confuse that with safe. Crypto can indeed be very strong but is extremely unsafe.
Have you ever tried to clean up from a root private key compromise? I wrote previously (http://rdist.root.org/2009/05/17/the-debian-pgp-disaster-tha...) about how a one-line change in the PRNG had compromised every DSA private key used on Debian/Ubuntu. Not generated, used. The properties of DSA make it such that your private key is directly revealed to any attacker who knows some bits of your PRNG output. I hope that emphasizes how dangerous crypto is, because it is so sensitive to its prerequisites.
With 'normal' code, if it's broken, something doesn't work, and you know to fix it. With crypto, if it's 'broken', all the valid requests still work, and you don't know that anything's wrong.
In fact, as far as I know, the only way to know if your crypto code is 'working', is to prove it ... in the form of, if you can somehow break my crypto, you will also be able to break problem X, where X is a problem the crypto community has generally accepted to be hard to solve.