Any subsequent requests to a site will trust that cookie as long as it decrypts properly.
You want sick? Here's sick.
An AES block is 16 bytes long. You want to encrypt the lyrics to "Yellow Submarine". You can't just repeat AES for each 16 byte block, because then you can tell where the words "yellow submarine" --- 1 AES block --- occur: they'll encrypt to the same block. So you use CBC mode, XOR'ing each plaintext block to the previous ciphertext block, creating a unique ciphertext every time you encrypt those lyrics. But "Yellow Submarine" is 902 characters long; the last block is 6 bytes short. So you pad the message which a count of the pad characters --- 06h 06h 06h 06h 06h 06h.
With me so far?
Decrypt the message. Check the padding: it should repeat as many times as the value of the last byte. If not, you decrypted badly. Send an error to that effect.
Hey guess what! I can decrypt parts of your message!
If I stick a random AES block in your message, it will scramble the padded block. Every once in awhile, that scrambled message will end in 01h. 01h is valid padding. The message will be gibberish, but you at least won't tell me it had bad padding.
You wouldn't tell me if you decrypted to bad padding if I generated 02h 02h either. But that's much less likely than 01h.
Now I know that your plaintext XOR my random block produces a last byte of 01h. Solve.
Now my point: this is actually way old news --- back to Bleichenbacher and Vaudenay and probably before that (I'm not the resident expert) --- but attacks like this have broken peer-reviewed versions of TLS, the most peer-reviewed crypto protocol ever designed.
Don't build crypto.
Some quick back-story
Vaudenay described this attack almost 10 years ago, in this paper:
It's very readable for a crypto paper.
We blogged about padding oracles in our AES post 2 years ago.
Then Thai Duong and Juliano Rizzo independently re-discovered them and went on a tear looking for software vulnerable to the flaw. Just a few months ago, they busted up Java Server Faces with the exact same vulnerability.
This vulnerability is also a galactic pain in the ass to address:
* It exploits the common-case error handling behavior of most web stacks (generate exception, do something that visibly indicates to the user that an exception was generated)
* It's not enough just to stifle the errors; you have to make observable behavior in the bad-padding case identical to the good-padding case.
* If you're MAC'ing packets as well as encrypting them, you also have to make sure the timing is the same in the bad-padding and good-padding case, which means you have to "pretend" to MAC the bad-padding packets, which is extremely counterintuitive (you have to catch an exception then pass "something" to a MAC verification routine).
Some food for thought
It's 2010, vulnerability research is no longer a cottage industry (it's hundreds of millions annually), and we're just now hearing about exploits of one of the simplest crypto flaws there is (there is almost no math to this one).
Software security people simply don't read crypto papers.
Crypto researchers, at least until recently, don't break software.
God only knows how much other scary stuff is buried in those papers waiting for an enterprising bug hunter to try them out.
This doesn't depend on the algorithms you use. The padding oracle attack works just fine with DES-EDE, Serpent, AES or Twofish; HMAC-SHA1, HMAC-SHA256, and (probably) HMAC-MD5 are all equally effective at combating it.
If you need to put sensitive data in cookies, you're doing it wrong!
Note that (a) lots of people have screwed up HMAC recently and (b) HMAC isn't a solution to the padding oracle problem unless you take pains to make sure it isn't.
(Unless I'm mistaken and there's other advantages for choosing encryption over MAC?)
Interesting, how could you exploit padding oracle when you're using HMAC?
In sign-then-decrypt designs --- which, from what I've seen, is what most designs are --- you can still exploit a padding oracle when the app catches padding errors and skips the (pointless) MAC verification for a packet it plans to discard anyways.
If a developer writes a cookie, it's not encrypted and the user can easily change it. Just normal cookies.
If a developer writes a session cookie, ASP.NET encrypts it behind the scene and stores it in a cookie. Because the user doesn't know the encryption key, he can't change the session cookie. The developer doesn't do any encryption himself, he just tells ASP.NET "Please store this value at the user, but he should not be able to tamper with it".
However, crypto is hard, so because of the issue mentioned in this article it is possible to tamper the data.
Could someone correct me if I'm wrong?
Shouldn't that be 'at least as many times as'? After all, the 902th byte could be a 06h, too.
Do you know of any statistics on how often attacks on web applications are cracks of the crypto involved as compared to many of the other weak links in the chain? Seems like hackers/crackers will find much easier ways to circumvent the system, even if the crypto has weaknesses as outlined the above article.
SQL Injection happens now and again but less often, possibly because with a lot of the banks we deal with they're not necessarily using an SQL backend as opposed to some sort of broker for backend systems. If you can abuse the broker though (and that is a common theme) then there's all kinds of fun/problems to be had.
I think if you re-read my comments in the context I wrote them in, you'll see that all I'm saying is that there are heavily-audited apps for which a padding oracle flaw would be a reasonable first step for an attacker.
When XSS was discovered, we had one large financial institution that we did testing for make us go back and retest all the applications we'd tested for them for XSS (this was about 20 online banking apps), and for about the next two years, it would pop up in tests for other clients.
I can safely state that now it's pretty rare though, as the majority of the applications we're looking at have been tested annually, and the low hanging fruit has been picked a long time ago.
It seems that weaknesses like these, while problematic and fun to discuss, are not really the ways in which web applications are generally attacked.
You aren't going to break a Fortune 100 bank's retail app with a textbook SQLI. Those apps have been audited several times over. It would follow from your worldview that those apps simply don't get attacked. Of course they'll get attacked.
Also: padding oracles? HMAC timing attacks? Not rocket surgery.
Pick the random Fortune 100 bank app and wouldn't it be more fruitful to attack the pc's of the clients rather than the server? You've got probably millions of users of the application, most of which are barely secure in the first place. As you said, the web server side is going to be the toughest link in the chain. Not impervious, but certainly difficult. Seems much more likely the hacker/cracker will target the users. In such an attack, the crypto is not the thing attacked.
The bug isn't being able to decrypt cookies, it's thinking that encrypted cookies are useful.
I'm pretty sure I already know my bank balance, so hiding it from me seems pretty pointless. And like I said, protecting an app from its users by encrypting cookies is a stupid idea from the start.
Can I ask, what's the psychology of knee-jerk "this vulnerability doesn't matter" comments? You clearly don't know what the flaw is, and that's fine, but I'm really curious: why do you want it to be pointless? Isn't the world a more interesting place when ASP.NET can blow up spectacularly because of a 2-line programming error?
It's a lot better for my bank to not send me anything to tamper with. Then it doesn't matter if the crypto works or not, because there's nothing I can tamper with.
Why is it pointless to point out that there's a better way to build apps that avoids the entire flaw?
"Nothing to see here" as they say.
It's OK to be skeptical about things (god knows I am), but it's important to be clear about where your actual knowledge ends. I think one thing that's confusing people is that the talk hasn't actually been presented yet.
I still suspect this is being overhyped. Being able to forge the auth cookie 100% of the time doesn't change the fact that you need a server-recognized value to actually forge.
This seems like it could indeed badly damage apps that stash important things in client state expecting it to be secure, but a lot of bog standard asp.net apps will be unscathed, unless I'm missing some killer detail. We'll see.
Edit: If the contents of a forms authentication cookie are not session-bound and assume that crypto == safe, that could certainly make things interesting. No idea though.
Edit2: Increasingly convinced that this could enable devastating attacks on forms auth (a large proportion of asp.net apps to be sure) - the content of a forms auth ticket appears to be trivially constructed.
The first thing you learn about error handling and security is to not send back error messages that have useful information that hackers could use for penetration; that is programming 101 stuff. Therefore, any decent ASP.NET app does not send back the error messages that the article talks about - the app devs hide those behind, "Oops! Sorry 404!" type stuff. It's super simple and done on almost all ASP.NET sites.
So yes, there is a vulnerability, but this is sort of like the SQL Server bug from 5+ years ago that depended on their being no password for the server admin account. Yes, certain people will be bitten, but by and large "professionals" will have covered for this already.
And no, "the generic error" is not all they need b/c the developer says "Oops 404!" as the generic error or "Oops Server Error 500". Nothing substantial and no information that would give away what happened or why.
Was it your perception from this report that the flaw here was developers leaking crypto secrets in the text of their errors? You were wrong.
Here is a clue: they are using ASP.NET behavior to generate a one bit signal from the target. Their attack requires many tens of thousands of requests. That's about as much as I can say.
The HTTP response code is the only information needed for the attack.
200 vs. 500 vs. 404