Monday, 27 September 2010

XML Character Support

One of the projects I'm working on heavily uses a ReST API and performs a lot of XML processing. Recently we've had some serialisation errors when processing some of the XML, resulting in a .Net error throwing:

System.InvalidOperationException: There is an error in XML document (1, XXX). ---> System.Xml.XmlException: XXX, hexadecimal value XXX, is an invalid character.

So I examined the XML payload and could see it contained a non-pritable/control character. I raised the case with the API developers but I found myself curious to find a definitive list of what characters are valid in XML documents. I soon found the Extensible Markup Language (XML) 1.0 Specification, which contained a section regarding the supported XML characters.

You can encode a massive range of characters in XML documents, but there are some non-pritable/control characters that are not supported. Legal non-pritable/control characters include tab (xx09), carriage return (xx0D) and line feed (xx0A). For printable characters it's the legal characters of Unicode and ISO/IEC 10646.

Useful Links

Tuesday, 21 September 2010

Padding Oracle Crypto Attack (Update)

The ASP.Net vulnerability that was announced prior to the EkoParty conference in Argentina last week, initially sounded a lot like a whole lot smoke and not much fire. I read the summary of the exploit and belittled it in a blog post, telling people not to panic. I did however decide to review the slides of the technique used to expose the vulnerability as it all sounded rather interesting. However, I wish I hadn't as it soon came to light that the vulnerability was more serious than previously thought. Microsoft agreed and released a security advisory.

arghhhhhhhh

What can the attack do?

The attack is relevant to all versions and flavours of ASP.Net and is able to decrypt ViewState data, not an issue as long as you don't store sensitive info in the ViewState - which you shouldn't!

The real issue arises if using ASP.Net 3.5 SP1 or above, the attacker could use this encryption vulnerability to request the contents of an arbitrary file within the ASP.Net application i.e. the web.config.

How the does it work?

The attack makes use of cryptographic oracles. An oracle in the context of cryptography is a system which provides hints as you ask it questions. ASP.Net acts as a padding oracle in this case. Allowing an attacker to send chosen cipher text to the server and learn if it was decrypted properly by examining which error code was returned by the server (and even time taken). If the attacker makes enough requests, they can learn enough to successfully decrypt the rest of the cipher text. The attacker can then alter the plain text and re-encrypt it as well.

Silence that Oracle!

By returning only one application error page no matter what the error effectively silences the oracle and the attacker can no longer gain the info they need to decrypt your encrypted site data. Not ideal in web apps,

Anything else?

Yeah actually! Any sensitive files on your server within your application should be encrypted. For example your connection strings or your username and passwords in your web.configs should be encrypted.

Useful links

Thursday, 16 September 2010

Padding Oracle Crypto Attack Affects Millions of ASP.NET Apps

So I saw this headline on Slashdot IT and it immediately made me pay attention. So I loaded up the ASP.Net security vulnerability article detailing the exploit and started reading.

In short, it totally destroys ASP.NET security

It soon became obvious that the article was a little bit sensationalist to say the least (see quote above). Basically the exploit is low-risk. You should only be worried if your applications aren't communicating over SSL and if you have put sensitive information in you ASP.Net application's cookies and are trusting the cookie data blindly. Sensitive data should all be stored server side - but you knew that anyway!

Needless to say, I've not wrote any code lately that checks for an SuperUser=true value in the cookie!!!

Tuesday, 14 September 2010

MailMessage's Subject ArgumentException

Just a quickie today... if you get an ArgumentException when setting the subject on the .Net MailMessage object (or on the constructor) like this...

System.ArgumentException: The specified string is not in the form required for a subject.

You'll want to cleanse your string input for non-printable characters. The most likely culprit is a carriage return or line feed. Which is "\r" or "\n" to the C# developers :)

Monday, 16 August 2010

Head of Applications Development

So all has been quiet on the blog front for a few weeks now, but I have a valid reason this time - honest!

I've been busy getting to grips with my new role at Esendex as 'Head of Applications Development'. Neadless to say I'm very busy at the moment with planning, coding (although not as much coding as I'd like) and improving the applications team's agility. At the moment the days are passing me by very quickly!

I've got lots of blog post ideas so as soon as I get round to it they'll be up. Expect more Asp.Net MVC, TDD and hopefully some BDD posts popping up very soon indeed :)

Thursday, 24 June 2010

Multiple types were found that match the controller

I'm starting to make use of the new Areas feature in my MVC 2 applications. I've found it great for separating my applications into distinct sections rather than staring at a massive list of controllers/views all bundled into one folder. I came across an issue when I created a controller with the same name as a controller within a different or the default area:

Multiple types were found that match the controller named XXXXXXXX...

I thought it was a little cheap of Microsoft requiring you to give your controllers unique names across all areas. I was relieved to find out giving the same name within different areas is perfectly OK, you just need to specify the full namespace for the controller when setting up the route for it, like so:

public override void RegisterArea(AreaRegistrationContext context)
{
 context.MapRoute(
  "Members_default",
  "Members/{controller}/{action}/{id}",
  new { controller = "Home", action = "Index", id = UrlParameter.Optional },
  new string[] { "MyWebApp.Areas.Members.Controllers" }
 );
}

I knew Microsoft wouldn't let me down ;)

Friday, 18 June 2010

Mock ControllerContexts in ASP.Net MVC

After performing an upgrade to MVC 2 for a web application last week, I had a number of tests failing. This gave me an opportunity to refactor some controller tests and create a base class for my controller test classes. This new base class is straight forward and allows me to mock HttpRequestBase and HttpSessionStateBase easily on the mock ControllerContext - it also has an overload for mocking AJAX requests too. I expect this class to grow in time but it serves my needs for now:

public class TestController
{
 public static ControllerContext GetMockControllerContext()
 {
  return GetMockControllerContext("GET", false, null, null);
 }

 public static ControllerContext GetMockControllerContext(string httpMethod, bool isAjaxRequest)
 {
  return GetMockControllerContext(httpMethod, isAjaxRequest, null, null);
 }

 public static ControllerContext GetMockControllerContext(Mock httpRequestBase, Mock httpSessionStateBase)
 {
  return GetMockControllerContext("GET", false, httpRequestBase, httpSessionStateBase);
 }

 public static ControllerContext GetMockControllerContext(string httpMethod, bool isAjaxRequest, Mock httpRequestBase, Mock httpSessionStateBase)
 {
  var headerCollection = new NameValueCollection();

  // Add header value for ajax requests
  if (isAjaxRequest) headerCollection.Add("X-Requested-With", "XMLHttpRequest");

  if (httpRequestBase == null)
  {
   httpRequestBase = new Mock();
   httpRequestBase.Setup(r => r.HttpMethod).Returns(httpMethod);
   httpRequestBase.Setup(r => r.Headers).Returns(headerCollection);
   httpRequestBase.Setup(r => r.Form).Returns(new NameValueCollection());
   httpRequestBase.Setup(r => r.QueryString).Returns(new NameValueCollection());
  }

  if (httpSessionStateBase == null)
  {
   httpSessionStateBase = new Mock();
  }

  var mockHttpContext = new Mock();
  mockHttpContext.Setup(c => c.Request).Returns(httpRequestBase.Object);
  mockHttpContext.SetupGet(c => c.Session).Returns(httpSessionStateBase.Object);

  return new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock().Object);
 }
}

Friday, 11 June 2010

Time to Upgrade to ASP.Net MVC Web Apps to MVC 2?

Wondering if you should be upgrading to ASP.Net MVC 2? It is worth some serious thought as there's some powerful new features, the upgrade process is nice and simple, plus there aren't many breaking code changes. Why not take a peek at what's new in ASP.Net MVC 2 and I bet you'll see at least a handful of features that'll get you itching to upgrade ;)

If you decide to upgrade your web application then review the MVC 2 upgrade notes. They include instructions for upgrading manually or you can choose to use the upgrade tool. I've used the upgrade tool and it seems to work great for most people - but not me, I had two problems :( After the conversion completed I compiled my project and got an error:

It is an error to use a section registered as allowDefinition='MachineToApplication' ...

...I managed to fix this without pulling my hair out though. The only other issue I had was around 10% of my project tests suddenly started failing; a result of some change to the controller context processing (this resulted in me improving my controller tests by creating a base TestController). Again this was a nuisance rather than a show stopper - the upgrade was worth the effort :)

Thursday, 10 June 2010

IIS 6 Application Pools for Beginners

Application pools allow you to configure one or more web applications to a worker process. An application pool is separated from other application pools by worker process boundaries. So what does this mean? ...An application in one application pool is not affected by problems caused by applications in other application pools. This along with sensible recycling of your application pools, results in your web server being more efficient and reliable.

By default IIS 6 dumps everything into one application pool. So as you add new web applications to your server you should consider logically grouping them into pools. Due to there being an overhead for each application pool it makes more sense to group the web applications into related pools rather than just create a pool for each web application.

Recycling Your Application Pools

To keep your sites working efficiently your should configure IIS to periodically recycle your application pools and recycle them when they become unstable (using too much memory/cpu etc). Recycling cleans up memory fragmentation, memory leaks, abandoned threads and other bits of unwanted clutter. Note that when an application pool recycles, ASP.Net session state information stored in-process is lost for that pool, however other pools are not affected. If this is a problem then you'll need to use another session state mechanism for your ASP.Net web applications.

Application Pool Recycling Events

It's important that you review why your application pools are being recycling. For example, if you have a pool recycling every 30 mins due to excessive memory use then you have an issue with that applcation's code and it needs looking at. Event logs for application pools are off by default, to enable them see this Microsoft KB article.

Security

When you configuring your application pools you can configure the identity of each worker process to run as a different user and should consider how to configure application pools for application security. For example, you might need to create separate application pools for applications that require a high level of security, while allowing applications that require a lower level of security to share the same application pool.

Convinced?

Hopefully with this post you can see the benefits of spending some time in setting up your application pools in IIS and you've made a step in the right direction for improving your web server's reliablility and efficiency :)