A Safer Site
Monday, June 15, 2015 6:34 PM , edited Thursday, June 18, 2015 12:06 PM umbraco
If you were at CodeGarden 15 and have attended Chris Gaskell Securing your Umbraco session, you might have found yourself suddenly wondering whether your nice Umbraco site was safe at all. I know I did.
So, back home, I fired a tool he mentionned, ASafaWeb, against this site and got the result below. Oh my—orange and red—reasons to be scared!
OK, so it is time we go fixing.
Excessive headers and Clickjacking all come down to http headers. It looks like I am returning the
X-AspNetMvc-Version headers, and I am missing the
X-Frame-Options header. Should be easy to fix, right? Well, considering the number of blog posts listing near-voodoo magic solutions, it is not.
I initially decided that NWebsec looked fine. Installing this tool (as a NuGet package) in the web application modifies the
web.config file, registers a new module and adds an empty configuration section, where one can copy some settings from the Getting Started section of the documentation. Rebuild, reload, and headers look perfect.
Yet ASafaWeb still complains, because our error page still has the
Serverheader. Oh, and ASafaWeb triggers the error by reaching the
/trace.axd page, because trace is disabled on the live server. We have two problems here:
- Error pages should not have the
Serverheader. Looks like you cannot really get rid of that header in every situation but by using a native IIS module. In some cases, NWebsec cannot do it by itself. Ok, StripHeaders to the rescue. It needs to be installed on the server (hey, it's native IIS). Fixed.
/trace.axdshould not raise an error. Using the IIS Rewrite module, we add a rule to redirect to a non-existing page on the live server, hence triggering a proper 404. Fixed.
Now that we have StripHeaders installed, maybe we do not need NWebsec anymore. But that would mean figuring out the anti-clickjack by ourselves... we will be running both.
Custom errors is easy to check: just hit eg www.zpqrtbnk.net/< (note the "lower than" character) and it triggers a "potentially dangerous request" exception, which on the live site translates into a YSOD explaining how to manage custom errors in
web.config. Not pretty.
And strange. I do have a module handling the
HttpApplication.Event event, logging the exception to disk, and writing the content of a nice html file back to the client. How come it does not show?
Well, not all errors are "500" errors. The "potentially dangerous request" mentioned above is a "400" error. So I have changed my condition to output the html file if the status is greater than, or equal to 400, but not equal to 404.
And then, if you really really want to make sure that neither ASP.NET or IIS will try to be clever and manage the error by themselves, you want to end your handler with:
context.Response.TrySkipIisCustomErrors = true; context.Server.ClearError(); context.ApplicationInstance.CompleteRequest();
And now we have a nice Umbraco-managed 404 page, a nice 500 page that triggers on real errors, and
trace.axd just causes a 404. Are there other ASP.NET pages that cause errors instead of 404? Pretty sure. Why do static page 404 (eg a JPG) display a blank page? No idea. But I am running out of time: will deal with it later.
Safer it is
Fire ASafaWeb again, and sure enough, it's much happier.
So, I am feeling better. However, call me paranoid, the idea of having the Umbraco back-end publicly accessible annoys me a lot. I mean, we try to hide our server version, our ASP.NET version, but we still reveal that we run Umbraco by displaying the back-end login screen?
This website runs a custom module that blocks all accesses to the
/umbraco path by redirecting to the home page, unless you first hit a url looking like
/76d161694013457bbf442075573963fd. Doing this creates a session cookie and unlocks the back-end. Granted, it's probably security through obscurity, but I feel better knowing that, should a security issue in the back-end be published tomorrow, script kiddies would have a hard time exploiting it on my site.
How do you secure your website?
When configuring NWebsec, make sure the
X-Frame-Option policy is set to SameOrigin and not Deny, as that breaks parts of Umbraco's backend.