Do we really need CAPTCHA's to prevent robots posting to our web forms? Not if you run ASP.NET 2.0. Whether you use a form for member logins, blog comments or a web shop you want to keep it as secure and tamper proof as possible. Brute force attacks on a login form performed by robots or spammers on the blog comments are scenarios you can avoid by leveraging existing ASP.NET 2.0 features.

Event validation

Event validation makes sure that a postback comes from a control on the page and not a direct POST request sent by an application (read robot).

ASP.NET has event validation turned on by default, but many people turn it off for various reasons. One reason is that their web application registers exceptions caused by the event validation. So does mine, but that is when an unauthorized post request is performed. Don’t turn it off.

ViewstateMAC

When ViewStateMAC is enabled it encrypts the ViewState so it cannot be tampered with by evil doers. ViewStateMAC is not enabled by default, so you have to do it in web.config manually like so:

<pages enableViewStateMac="true" />

When enabling ViewStateMAC you must also add a machine key to the web.config so that all the servers in a webfarm use the same encryption and decryption key. Otherwise you can end up with invalid ViewState. Here is an example on such a machine key.

<machineKey validationKey="D9F7287EFDE8DF4CAFF79011D5308643D8F62AE10CDF30DAB640B7399
BF6C57B0269D60A23FBCCC736FC2487ED695512BA95044DE4C58DC02C2BA0C4A266454C"
      decryptionKey="BDAAF7E00B69BA47B37EEAC328929A06A6647D4C89FED3A7D5C52B12B23680F4"
      validation="SHA1" decryption="AES"
    />

You can take it a step further and add a user key to the ViewState. That locks the ViewState to a single user and makes it even harder to tamper with. Read more on the user key here.

All the rest

These are two build-in technologies that can be used, but you still have to do your custom form field validation etc. No CAPTCHA is needed when using these two techniques. All it requires is that you use a <form runat="server"> and the standard postback feature of ASP.NET to post the form. If you don't believe me, try it out. It does eliminate the use of CAPTCHA's.

I’ve always been a little annoyed by the fact that ASP.NET websites sends the version number as a HTTP header. For an ASP.NET 2.0 application this is added automatically to the headers and you cannot remove it from code. This is what it looks like:

X-AspNet-Version => 2.0.50727

Why would it be necessary to send this information about your application to possible hackers? It doesn’t make sense. Maybe it’s because it allows for statistics to be collected about what versions people are using. Microsoft could then send a crawler to investigate all the websites in the Windows Live search database. I don’t have a problem with that; it’s the hackers I fear.

The other auto-injected header X-Powered-By => ASP.NET is fine with me. It’s easy for people to see by the .aspx extension that you run ASP.NET anyway, so this is not a security issue but still a little annoying that you cannot remove it from within your ASP.NET application. You have to remove it from the IIS.

Then the other day I was playing around with the web.config and by accident noticed the httpRuntime tag and its enableVersionHeader attribute. For some reason I’ve never noticed it before. If the enableVersionHeader attribute is set to false, the X-AspNet-Version header will not be sent.

So, to get rid of the X-AspNet-Version HTTP header from the response, just copy this line into the web.config’s <system.web> section:

<httpRuntime enableVersionHeader="false" />

I think if it was such a big deal to get rid of it, I’d probably done some more research and found this trick years ago. Anyway, I just thought I would share it with you.

To check the HTTP headers sent from your own site, you can use one of the many online tools like this one.