Microsoft keeps calling this a ‘workaround’ but it’s mitigation at best – sure, for the majority of applications it may be all that’s necessary, but it falls short of cross-the-board prevention. It’s not clear why they’re not more open about the cases that aren’t covered by the suggested workaround but it doesn’t take more than simple reasoning to reveal them. If you’re really concerned about the security of your application, keep reading.
Let’s go back to basics and look at where this issue stems from – all you need to do is differentiate between these three cases…
When the application is passed an encrypted value, it responds in one of three ways:
- When a valid ciphertext is received (one that is properly padded and contains valid data) the application responds normally (200 OK)
- When an invalid ciphertext is received (one that, when decrypted, does not end with valid padding) the application throws a cryptographic exception (500 Internal Server Error)
- When a valid ciphertext is received (one that is properly padded) but decrypts to an invalid value, the application displays a custom error message (200 OK)
And depending on how your application uses encryption, you are still able to do this even with a constant error page – here’s one blogger’s explanation (misses the point, IMO):
How about Microsoft’s workaround?
Well, while the workaround contains a really valuable information, relevant for every system (as for not disclosing the real error), and it will prevent the automated tool released by the researchers to hack your system, it will, by far, NOT protect you from a potential attack!
How so? The workaround assumes that the potential attacker will look for an HTTP error response status (500), or for an error page containing a specific exception message. However, it is enough for attacker to recognize an abnormal, or just different system behaviour on certain requests.
Let’s get back to our ASP.NET system that stores an encrypted sensitive information in a cookie. Each request, the system will probably decrypt this information and use it. In case the ciphertext in a cookie is invalid, an exception will be thrown, and the system may act according to one of the following scenarios:
· Return a 500 error response - very user unfriendly!
· Return a default ASP.NET YSOD exception page - extremely bad in production environment!
· Return a page stating only the exception’s message - also very bad!
· Return a constant page, stating there was an error, without providing details– a good practice, this is actually the Microsoft’s workaround
· “Swallow” the exception, and behave like the cookie does not exist. The response may be a redirect to another pager, or just a a slightly changed HTML (instead of user’s name, a “login” link) – This is the way ASP.NET Forms Authentication works.
Note that every one of the possible responses is different from the normal one. Even the last scenario I’ve described above, as clean as it is, still returns a distinctively different response. Therefore, an attacker can take advantage of it, and write a simple script that infers this abnormal behaviour to an Invalid Oracle’s answer. It is that simple!
That’s mostly right except that it’s not sufficient to detect any error condition – you need to be able to discern between two specific error conditions (ciphertext not correctly padded vs. ciphertext is correctly padded but decrypts to an invalid value).
If visitors to your site can do this, you’re still vulnerable. Here’s a scenario: you don’t rely on Forms Authentication, but instead have a custom authentication scheme that relies on encrypted cookies. If an invalid cookie is submitted, you treat the user as anonymous; but if an exception is thrown during decryption, Application_Error kicks in. This scenario, not entirely uncommon, still allows the attacker to replay the request and differentiate between the 3 possible replies.
How does your application respond in these scenarios and how confident are you of the answer?