How ASP.NET Security Vulnerability affects Kentico CMS

   —   
There is a lot of buzz about recently published ASP.NET security vulnerability and it truly is important. Read this post to see how it may affect your sites ... right now if you can!
Hi there,

As you probably already know, there is a very serious bug in ASP.NET security that allows the attacker to get sensitive information from ASP.NET web site. You can find more details about it here:

http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx

and here are the FAQs:

http://weblogs.asp.net/scottgu/archive/2010/09/20/frequently-asked-questions-about-the-asp-net-security-vulnerability.aspx

I didn't want to just mirror the same information that is already all around the internet so before I wrote this post, I spent the whole last day in checking the details of this issue, how it really works and what could be potential options to prevent that but keep your web site functionality intact. From the posts above, you see that the recommended solution is not exactly most friendly one in all cases. But I can definitely confirm that it works os it may be at least temporary solution. 

What is important is that this is in the core of the .NET, and heavily used feature (basically even standard WebForms model and AJAX are built on it), so everything out there is potentially affected by this, no matter if you use Kentico CMS, Sharepoint or CMSxyz built on ASP.NET.

What exactly is the security issue?

I do not want to judge any programmer that is responsible for this but the fact is that the creators of ASP.NET Framework let the door for the attackers half open.

What ASP.NET Framework provides is a handler WebResource.axd (or ScriptResource.axd, doesn't really matter), that provides a way how to retrieve physical files of any kind from your web file system. You can see how this is supported if you add something like this on your page:

<asp:ScriptManager runat="server" ID="manScr">
  <CompositeScript>
    <Scripts>
      <asp:ScriptReference Path="~/web.config" />
    </Scripts>
  </CompositeScript>
</asp:ScriptManager>


I intentionally used path to web.config, because that is exactly where reported the problem lies. If you look at the output of the page, it renders something like this:

<script src="/ScriptResource.axd?d=EfRKJEgW1Tec-zA1PuIaXerT9kpl0_QJyr7R4g6yvb-DNebY3LZEthKYxoQwNMMW0" type="text/javascript"></script>

And if you query the URL, you simply get the web.config code. This is how the attacker is able to get your sensitive data which doesn't have to be only the machineKey, but can be also your connection string to database or anything else for that matter.

As you surely guessed right, the "d" parameter contains the locator of the resource, somehow encrypted. So far, it seems fine until somebody is able to guess or encode the resource identificator. Once he can get the correct one or the encryption key, he can access anything and simply generate those keys.

This solution of theirs basically has only single point of breach which is the encrypted resource key itself. If there would be additional precaution, like allowing only certain types of files to be retrieved, the security issue wouldn't be that bad for everyone, but it unfortunately is.

How the attacker gets the key?

Although breaking the cipher via brute force may seem hard enough, there are ways how to get there quite easily, if the solution isn't robust enough to eliminate just every possibility.

What is typically used to break the ciphers is something called Side channel. Side channel is an information of any type that can leak out from the process and tell the attacker how his particular attack proceeded. Side channel can be really anything and it isn't anyhow based only on software implementation, it can be also part of the hardware. For example, if you try to hack the ATM with electronic device connected to your laptop simulating the credit card, even the time in which the particular request is processed (e.g. longer if succeeds, shorter in case of error, or specific number of cycles executed) can tell the attacker how successful he was until he breaks the cipher going the right way. The creators of sich devices fight against this by incorporating random waits or ensuring that any operation takes same amount of time using delayers. These side channel clues serve the attacker as some sort of oracle to reduce the number of options. Same thing with the software implementations. Any information that can leak out from any security process significantly reduces the number of options. If you want to know more about side channels, try to start here:

http://en.wikipedia.org/wiki/Side_channel_attack

In this particular case of ASP.NET vulnerability, the Side channel clearly is the difference between "Page not found" and "Cryptographic exception". You can get the first one if you link to the non-existing file, and the second one if you attempt to change the URL to the resource.

Very bad thing about AES algorithm that is used by these resources is that it already has known side channels specific to padding of the encrypted data so it is not that hard to break it as you can see here:

http://www.youtube.com/watch?v=yghiC_U2RaM&hd=1

This is exactly what an attacker can do.

One other issue of this is that the length of the encrypted resource key is depending on the length of the data value which means the attacker can use much shorter data to attack and further reduce the number of options. That is another side channel in this particular case.

So what the attacker does is he attempts to partial-guess (using the oracle) the machine key used for encryption of particular key, either one that he chooses or some default one (WebForms link script WebForms.js which has known format of decrypted data and is used on almost any web site implemented through ASP.NET). He basically requests the files until he gets 404 which means the cryptography part has succeded. Once he gets the machine key, he can generate any resource key he wishes. Specifically with the web.config, the decrypted key looks like:

Q|~/web.config|#|298f20c0

Not exactly sure what is the second part (timestamp or hash maybe) but clearly the first part locates the resource. So the attacker generates the URL using this resource locator, and requests the resource. Now he gets the web.config file with all the sensitive information or any other file your web site can access the same way.

How to prevent that?

Now you know how it works on the attacker side which is important so you can understand why the recommended solutions are the way they are. What we need to do is basically to close the side channel which in this case is the error reporting. That is why the official recommendation is to basically provide single error for any case. They suggest following settings:

<configuration>
  <system.web>
    <customErrors mode="On" defaultRedirect="~/CMSMessages/error.aspx" />
  </system.web>
</configuration> 


Note that do not even want to make a difference between Not found and other errors, since it would provide the same side channel.

While this seems OK, it may be a two-bladed sword. If you enable this on the whole web site, you may get some unwanted behavior because from that point on, all errors will be reported as the same giving the site visitor some false information (unless you can somehow cover all situations in your error file).

I understand why they are suggesting this, they want to prevent all potential bugs caused by the same thing in other locations.

So far, it seems to me like restricting the errors only for the particular files is also OK, because the errors we want to prevent come from these files only:

<location path="WebResource.axd">
  <system.web>
    <customErrors defaultRedirect="~/CMSMessages/error.aspx" mode="On" />
  </system.web>
</location>
<location path="ScriptResource.axd">
  <system.web>
    <customErrors defaultRedirect="~/CMSMessages/error.aspx" mode="On" />
  </system.web>
</location>


So adding this to your web.config should keep all your standard pages intact, while the side channel on those particular files is closed.

Other precautions

While all this may seem to be enough to do and you may think that you are safe, I am a little paranoic when it comes to security so I believe in quite opposite scenario. Hacking is a good businness nowadays and the hackers won't let such opportunity to slip between their fingers. You have implemented a precaution that itself is just a workaround and does not ensure you that it covers all potential side channels. Not only that, your web site could have been already compromised without you knowing that.

So definitely do not end here, but continue (in fact that is what you should always do, not only in this case):
  • Backup your site more often until the patch for this from Microsoft is ready.
  • When the patch is available, immediately apply it.
  • Implement the recommended workaround. If it doesn't break your web site functionality, use it on the whole web site. If it does, at least use the option with locations.
  • Check out all the news about this issue in case someone would find some other way that the workaround doesn't cover. You should do the same even after the patch is out just in case they didn't fix everything.
  • Check your security settings on all servers, if possible allow only the web server IP to access the SQL server.
  • If you have such option, use some flood control, as you could see on the video, it still requires a lot of requests in a short time, so if you prevent it in some way, you will have enough time to fight against it.
  • Check out your event logs on a regular basis and search for any too frequent error patterns.
  • If you have any suspicion that your web site could have been already compromised, require from all users that they change their passwords, change the machineKey and other passwords to other servers.
  • With Kentico CMS, you may at least temporarily disable the admin UI if you know you won't need it with following web.config key: <add key="CMSDisableAdministrationInterface" value="true" />
The patch they are preparing will probably use one of these approaches:
  • Limiting the files you can retrieve to just specific types (which may make some existing applications not work properly if they will use some "special" files, not Kentico case which is good).
  • Implementing other algorithm for encrypting the resource keys (which will be supported anywhere but will probably need some configuration change).
One way or another, you need to be careful no matter if you use Kentico CMS or any other ASP.NET application at least until the patch is out and applied and few weeks after that.

Unfortunately, we cannot fix this since it lies in the core of ASP.NET so you need to go with the workaround at this point which may and may not be good enough. What may be calming for some of you is that there are currently thousands of buggy web sites out there more important for the hackers than yours, but you definitely shouldn't count with it as a sure thing, especially if you have some enemies behind you.

In case you know any update on this or can add some more imporant information, feel free to post it into the comments. Thank you!

See you later ... hopefully with some nicer topic
Share this article on   LinkedIn

Martin Hejtmanek

Hi, I am the CTO of Kentico and I will be constantly providing you the information about current development process and other interesting technical things you might want to know about Kentico.

Comments

Martin Hejtmanek commented on

Hi,

You can use Firebug, Fiddler or some similar tools to see the output status code if you tamper with the resource URL. But you need to learn more about how those scripts work and their parameters. You can find some of it on ScottGu blog or in ASP.NET documentation.

Armysniper89 commented on

I noticed in my site which launched days ago errors in Kentico for WebResource.axd and ScriptResource.axd. I installed the patch that ScotGu mentions to fix this vulnerability but how can I test this and make sure these errors I am seeing from the same IP Address are being thwarted?

Martin Hejtmanek commented on

Finally. Thanks for sharing, Jim

JimS commented on

Looks like the patch will be available tomorrow...

http://weblogs.asp.net/scottgu/archive/2010/09/27/asp-net-security-update-shipping-tuesday-sept-28th.aspx

http://www.microsoft.com/technet/security/bulletin/ms10-sep.mspx

José Manuel Andrés commented on

Hi, guys and friends !

Well, thanks so much for your advise !!!

It is sufficient for I decide dont issue and use any more 'Windows' / "Bill Gate"'s Software. ...and he is billionar? He should need to devolve all money he had gain cent by cent !!!

Martin Hejtmanek commented on

Hi Lance,

If you use the location variant, or if you configure the extensionless through the 404 handler directly on IIS (see the documentation), then it will work.

Lance England commented on

Hi Martin,

Wouldn't removing the 404 break extensionless URL? Any work-around for that?

[statusCode="404" redirect="~/CMSPages/handler404.aspx"]

Thank you for your detailed explanation.

Jonas Stawski commented on

Another precaution can be to use the Dynamic IP Restriction plugin for IIS 7 (if you have Windows Server 2008 and above). Since this attack is kind of brute force you can limit the number of request an ip can make in an amount of time. Although it is in Beta i've been using it in my prod servers for quite some time.

http://www.iis.net/download/dynamiciprestrictions

This should also protect you from other types of attacks where the attacker is trying to find a side channel or a loophole in your code.

xmen commented on

Nicely explained, thanks

Martin Hejtmanek commented on

KLM: That approach is possible with any ASP.NET web site, but with Kentico CMS, it is much easier if you just go to the

Site manager -> Settings -> System

And set the "Error notification e-mail address" to your e-mail. Then you will receive all error notifications. You can also find all logged errors in the Kentico CMS event log (Site manager -> Administration -> Event log)

Martin Hejtmanek commented on

sphillips: Yes, locate some URL of the resource, it will look like this:

<script src="/ScriptResource.axd?d=EfRKJEgW1Tec-zA1PuIaXerT9kpl0_QJyr7R4g6yvb-DNebY3LZEthKYxoQwNMMW0" type="text/javascript"></script>

Then open the resource in a new window, it will give you the underlying file correctly. Then modify the "d" parameter anyhow and you should not get error code 500 (or 5xx), you should get 200 and the custom error page. It this works for any type of the resource on your page (meaning WebResource.axd, ScriptResource.axd), then the fix is working.

KLM commented on

Thanks for the article. What is the best way to have custom error page data sent to an admin's email address. Is this a good solution? http://seo-insights.blogspot.com/2009/09/aspnet-404-error-page-how-to-configure.html

THANKS!

sphillips commented on

in doing the <location> fix, is there an easy way to test the fix is working without performing the hack?

RK commented on

I'd like to thank Kentico for making security a priority as they develop their CMS. It's far too common these days to see websites being exploited by XSS, SQL injection, Viewstate hacking, session hijacking, etc., so I'm relieved to see that Kentico keeps up with the latest security news with respect to the .NET framework and web technologies in general. I work for a software security company and we use Kentico here, so obviously security is of the highest importance to us. Thanks again, Kentico, and keep up the good security work!

Martin Hejtmanek commented on

Hi Snappy. With the first option that does it globally, you need to replace the whole custom errors section and remove the 404 handler, too. With the other option with location, you just add them the same way as other locations in the web.config and keep the global section as is.

Snappy commented on

Where exactly do you put this? Do I simply replace the existing custom error configuration settings with this at the same location?

We need to remove the 404 handler too?

When I simply changed the built in configuration for custom erors to "on"...my server hands on a 404 error.

Brian McKeiver commented on

Ah, I assumed since the handler404 did a redirect it did not preserve the 404 status code and returned a 200. Makes sense. Should have checked it in Fiddler. Ill update my post

Thanks

Martin Hejtmanek commented on

Hi Brian,

Although this may seem safe enough and not that different from the recommended solution, it is different if you look at its behavior through Firebug or Fiddler. It depends on a specific exploit implementation, but the handler404 still returns 404 (at least in newer versions of Kentico CMS) so the attacker would still be able to recognize whether the error is somehow internal (general) or 404. So in the end he would still be able to exploit the web site.

See the RedirectToPageNotFound method in Global.asax.cs, that is the logic behind 404 if it occurs and if possible, it tries to preserve 404 code so search crawlers can interpret it correctly. A possible option in this case would be to explicitly set code 200 for all such requests coming there.

Brian McKeiver commented on

Thanks for the great post on the subject. I posted earlier this weekend about it here: http://bit.ly/aZLvQo, but your explanation rocks. I'm curious about what you think about my proposed solution ?