Hacking .NET and Startups

How to Securely Verify and Validate Image Uploads in ASP.NET and ASP.NET MVC

One of the more interesting things I had to do as part of building XAPFest was handle bulk image uploads for screenshots for applications and user / app icons. Most of the challenges here are UI-centric ones (which I resolved using jQuery File-Upload) but the one security challenge that remains outstanding is ensuring that the content uploaded to your servers is safe for your users to consume.

Fortunately this problem isn't too hard to solve and doesn't require much code in C#.

Flawed Approaches to Verifying Image Uploads

Here's what I usually see when developers try to allow only web-friendly image uploads:

  1. File extension validation (i.e. only allow images with .png, .jp[e]g, and .gif to be uploaded) and
  2. MIME type validation.

So what's wrong with these techniques? The issue is that both the file extension and MIME type can be spoofed, so there's no guarantee that a determined hacker might not take a js. file, slap an extra .png extension somewhere in the mix and spoof the MIME type.

Stronger Approach to Verifying Image Uploads: GDI+ Format Checking

Every file format has to follow a particular codec / byte order convention in order to be read and executed by software. This is as true for proprietary formats like .pptx as it is for .png and .gif.

You can use these codecs to your advantage and quickly tell if a file is really what it says it is - you quickly check the contents of the file against the supported formats' codecs to see if the content fits into any of those specifications.

Luckily GDI+ (System.Drawing.Imaging), the graphics engine which powers Windows, has some super-simple functions we can use to perform this validation. Here's a bit of source you can use to validate a file against PNG, JPEG, and GIF formats:

using System.Drawing.Imaging;
using System.IO;
using System.Drawing;

namespace XAPFest.Providers.Security
    /// Utility class used to validate the contents of uploaded files
    public static class FileUploadValidator
        public static bool FileIsWebFriendlyImage(Stream stream)
                //Read an image from the stream...
                var i = Image.FromStream(stream);

                //Move the pointer back to the beginning of the stream
                stream.Seek(0, SeekOrigin.Begin);

                if (ImageFormat.Jpeg.Equals(i.RawFormat))
                    return true;
                return ImageFormat.Png.Equals(i.RawFormat) 
|| ImageFormat.Gif.Equals(i.RawFormat);
                return false;


All this code does is read the Stream object returned for each posted file into an Image object, and then verifies that the Image supports one of three supported codecs1.

This source code has not been tested by security experts, so use it at your own risk.

If you have any questions about how this code works or want to learn more, please drop me a line in the comments below or on Twitter.

Bonus: How Do I Make Sure Files Are below [X] Filesize?

Since I had this source code lying around anyway, I thought I would share it: 

public static bool FileIsWebFriendlyImage(Stream stream, long size)
            return stream.Length <= size && FileIsWebFriendlyImage(stream);

Super-simple, like I said, but it gets the job done. Express the maximum allowable size as a long and compare it against the length of the stream


1The other important catch to note here is that I move the Stream's pointer back to the front of the stream, so it can be read again by the caller which passed the reference to this function.

If you enjoyed this post, make sure you subscribe to my RSS feed!

How to Create a Twitter @Anywhere ActionFilter in ASP.NET MVC

My newest project, Captain Obvious, got a fair amount of attention this week when it landed on the front page of Hacker News – one of the key features that makes the first version of Captain Obvious tick is Twitter @Anywhere integration.

Twitter @Anywhere is brand new and there isn’t much developer documentation for it – the way to think about Twitter @Anywhere is as a Javascript platform that allows you to outsource user authentication and registration to Twitter’s servers, and in exchange you get less hassle but also less intimate access to your user’s accounts.

One of the key features to integrating Twitter @Anywhere users with your ASP.NET MVC site is reading the cookie that Twitter sets after users have authenticated – this cookie contains two parts:

  1. The Twitter user’s unique ID, an integer representing their unique account (because remember – Twitter users can change their handles!)
  2. A SHA1 hash of the Twitter user’s unique ID + your application’s consumer secret – you use this to verify that the cookie was set by Twitter, since they’re the only ones who know your consumer secret other than you.

Naturally, if you are going to use this cookie as your authentication mechanism, then you are going to need to write your own Authorize attribute that allows you to validate the content’s of the Twitter @Anywhere cookie. Here’s the source code I use for doing that:



/// <summary>
    /// Controller Action Filter Attribute which requires that
    /// </summary>
    public class ValidTwitterAnywhereAttribute : AuthorizeAttribute
        protected override bool AuthorizeCore(HttpContextBase httpContext)
            var twitterCookieValue = httpContext.Request.Cookies["twitter_anywhere_identity"];
            var consumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"];

            return TwitterAuthHelper.ValidateTwitterCookie(twitterCookieValue, consumerSecret);


Here’s the relevant source code from the TwitterAuthHelper that I use to actually validate the hash in the cookie:



 public static bool VerifyTwitterUser(string twitterCookieValue, string ConsumerSecret)
            var results = twitterCookieValue.Split(':');
            var sha1 = new SHA1CryptoServiceProvider();
            var hash = BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(results[0] + ConsumerSecret)))
                        .ToLower().Replace("-", "");
            if (hash.Equals(results[1]))
                return true;

            return false;

I’m using this code in production and it works great – all you have to do to use it is decorate your controller methods with the [ValidTwitterAnywhere] attribute and it will behave just like Forms authentication if you have that enabled in your ASP.NET MVC app.

If you enjoyed this post, make sure you subscribe to my RSS feed!

ASP.NET MVC3 / Razor: How to Get Just the Uri for an Action Method

March 15, 2011 17:43 by Aaronontheweb in ASP.NET // Tags: , , // Comments (0)

I normally wouldn’t post something this small to my blog, but this issue bothered me so much when I was working on some Twitter @Anywhere + jQuery integration in ASP.NET MVC3 that I couldn’t help but share it.

Issue: You’re using ASP.NET MVC3 and want to be able to place a relative Uri for one of your ASP.NET MVC controller’s action methods in a block of JavaScript or anywhere else, and you want to be able to do it without having to parse it out of an Html.ActionLink output or anything else. What built-in helper method do you use?

Solution: The answer is that you use the Url.Action method, which yields a relative Uri, as you’d expect.

Observe the code below:

	authComplete: function (user) {
		// triggered when auth completed successfully
		$.post('@Url.Action("AnywhereTest", "Auth")');

And here’s the output to go along with it:

	authComplete: function (user) {
		// triggered when auth completed successfully

If you enjoyed this post, make sure you subscribe to my RSS feed!

Getting Started with AppHarbor – Heroku for .NET

January 14, 2011 12:53 by Aaronontheweb in ASP.NET, Startup // Tags: , , , , , // Comments (5)

I’ve a lot of friends who are proficient Rails developers, many of whom who have left .NET for Rails.

The one piece of consistent feedback that I hear back from them is that it’s the frictionless Ruby-on-Rails ecosystem that is so attractive; moreso than the Ruby language or the Rails framework itself (although they like that too.)

Heroku, above all others, is hailed as a step forward in developer productivity and easy web application hosting and deployment.

Platform-as-a-Service (PaaS), which is what Heroku provides to Rails developers, is powerful because it eliminates much of the need to manage and maintain infrastructure. Instead of managing a number of virtual machines on a service like EC2, you manage a number of application instances or some other such abstraction. PaaS combined with a continuous build / deployment system is a powerful combination indeed and allows for unparalleled productivity for agile web developers and startups.

.NET developers have had PaaS available to them for a couple of years in the form Windows Azure, but Azure is really meant to service the needs of rapidly growing services and cloud applications, not brand new projects that have no users yet.

AppHarbor fills two needs that are unmet by Azure – it makes it easy (and currently, free) for .NET developers to have access to a Git-enabled continuous development environment, something which our friends on Rails have had for a long time, and it supports the sorts of rapid build / test / deploy workflow that is common among agile groups and startups in particular.

This, in my opinion, makes AppHarbor the perfect starting place in the lifecycle for any new ASP.NET or WCF project.

Here’s how easy it is to get started with AppHarbor using their early beta interface:

Create a new ASP.NET project in Visual Studio


I’m using ASP.NET MVC3 here, which Microsoft just released-to-market yesterday. It’s great if you haven’t used it yet. You can download and install ASP.NET MVC3 here.

Initialize a new Git repository and commit the app


I use Git Extensions for Visual Studio to manage staging / commits, and it also includes the Git bash for Windows. I highly recommend it.



Now you’re all set for your initial deployment on AppHarbor.

Create a new application on AppHarbor


Follow the instructions for adding AppHarbor as a remote to your Git repository




Check the build status on AppHarbor


and then check out the app itself: http://appharbor-demo.apphb.com/ 

If you want to see a more substantial project on AppHarbor, check out Geeky Reads.

That’s all there is to it – it’s a matter of seconds to push and deploy new builds, and thanks to Git’s commit model, it’s effortless to rollback to previous builds. Compare this experience to the pain of doing a traditional web-deploy on a shared host or pushing a solution onto Azure – this is much simpler and faster.

AppHarbor can also hook a unit test project and use the success / fail of those to determine whether or not your build can be deployed, even if it is built successfully.



Want an AppHarbor invite?

If you’re interested in trying out AppHarbor yourself, click here to create a new AppHarbor account courtesy of the special invite code on this link. The AppHarbor team is eager for early adopters and feedback, so by all means please try it out and share your thoughts and experiences with them.

If you enjoyed this post, make sure you subscribe to my RSS feed!

How to Use Asynchronous Controllers in ASP.NET MVC2 & MVC3

January 6, 2011 12:01 by Aaronontheweb in ASP.NET // Tags: , , , , // Comments (6)

The primary reason I added asynchronous methods to Quick and Dirty Feed Parser 0.3 was because I wanted to use QD Feed Parser in conjunction with asynchronous controllers in ASP.NET MVC3.

MSDN has some excellent documentation which explains the ins and outs of asynchronous controllers in ASP.NET MVC, yet there aren’t many good examples of how to use it online. Given this, I thought I would make one.

Asynchronous Controllers in Theory

Here’s how asynchronous controllers work:

async controllers asp.net mvc

And in case my visual isn’t clear:

  1. A user sends a request to some resource on your server, i.e. GET: /controller/action
  2. Since the action method is part of an asynchronous controller, the processing of the request is handed off to a CLR thread pool worker while the IIS thread bails and serves other requests. This is the key advantage of asynchronous controllers: your limited, precious IIS threads get to off-load long-running, blocking tasks to inexpensive CLR worker threads, freeing up said IIS threads to serve more requests while work is being done in the background.
  3. The CLR worker thread diligently works away while the IIS worker thread gets recycled.
  4. The CLR worker thread finishes its task, and invokes the AsnycManager.Sync method and passes back some piece of processed data to be returned to the end-user.
  5. The AsyncManager hitches a ride on the first available IIS thread and passes along the processed data from the CLR worker thread into a special action method which returns some sort of consumable data back to the User, such as a View or a JsonResult.

Asynchronous controllers are all about utilizing additional, cheap CLR threads to free up expensive IIS threads as often as possible. In any situation where you have a long-running IO-bound task, they’re a good way to improve the performance of your ASP.NET MVC application.

Asynchronous Controllers in Code

To create an asynchronous controller, all you have to do is inherit from the AsyncController class:

public class FeedController : AsyncController

For every asynchronous action method you want to add to your controller, you have to actually supply two different methods:

// GET: /Feed/

public void FeedAsync(string feeduri, 
			int itemCount){ ... }

public JsonResult FeedCompleted(IFeed feed,
			int itemCount){ ... }

Both of these methods on the asynchronous controller support the same action method (“Feed”) and any request that goes to “Feed/Feed” in our ASP.NET MVC application will be served asynchronously.

Asynchronous Action Naming Conventions

Both methods have to follow these naming conventions:

  1. The first method is the worker method that actually performs the long-running task on a worker thread; it should return void; and it must be named [Action Name]Async.
  2. The second method is the output method which is joined back to an IIS worker thread by the AsyncManager; it must return a valid ActionResult derivative (View, RouteResult, JsonResult, etc…;) and it must be named [Action Name]Completed.

Full Asynchronous Action Methods

Here’s full source code from the asynchronous controller I used to build Geeky Reads, minus a bit of work I put in to use object caching:

public class FeedController : AsyncController    {
protected IFeedFactory _feedfactory;

public FeedController(IFeedFactory factory){
	_feedfactory = factory;        

// GET: /Feed/       
public void FeedAsync(string feeduri, 
			int itemCount){            


_feedfactory.BeginCreateFeed(new Uri(feeduri),
	async => AsyncManager.Sync(
		() => { 
		var feed = _feedfactory.EndCreateFeed(async);
		AsyncManager.Parameters["feed"] = feed;
		AsyncManager.Parameters["itemCount"] = itemCount;

public JsonResult FeedCompleted(IFeed feed, int itemCount){

return Json(FeedSummarizer.SummarizeFeed(feed, itemCount), 


Here’s what you should be looking at in this example:

AsyncManager.OutstandingOperations.Increment and .Decrement – the number of .Decrement operations must mach the number of .Increment operations; otherwise, the AsyncManager will time out operations that are running too long and the completion method will never return an ActionResult to the end user.

The accounting is pretty simple: you call .Increment at the beginning of your long-running operation, and .Decrement once your operation is finished and the results have been passed into the AsyncManager.Parameters collection, which brings me to my next point.

AsycManager Parameters and Argument Names for the Completion Method

Notice how the AsyncManager parameters “feed” and “itemCount” match the argument names for the FeedCompleted method – that’s not an accident. The AsyncManager binds its parameter collection to the FeedCompleted method arguments once the .Sync method completes, and this is what allows the asynchronous method results to be passed back to the consumer.

If you’d like to see the full source for this example, check it out on Github.

If you enjoyed this post, make sure you subscribe to my RSS feed!

How-To: Remote Validation in ASP.NET MVC3

ASP.NET MVC3 has been a major boon to my productivity as a web developer since I started using it at the beginning of November – the new Razor view engine has been attracting most of the attention with this iteration of MVC, but one extremely sexy feature has gone unnoticed thus far: Remote validation.

Remote validation was one of the new features added in the November Release Candidate (RC) for MVC3 – I had a chance to demo it in front of the LA .NET User Group last night and it was a monster hit.


You’ve all seen remote validation before – ever see one of these when you’re signing up for a service like Twitter?


That’s remote validation at work. Twitter, Facebook et al make an AJAX call to a remote service hook that checks the database to see if the username is available as the user types it. It’s a major user experience improvement as they get that feedback instantly instead of having to wait until after they fill out the rest of the form and submit it.

In the past with ASP.NET MVC you had to write your own custom jQuery scripts on top of the jQuery validation engine to achieve this end-result; in ASP.NET MVC3 this is taken care of for you automatically!

Let me show you how it works:

1. Decorate a model class with the Remote attribute

Take the class you want to validate and decorate the attributes you need to remotely validate with the Remote attribute.

public class NewUser
	[Remote("UserNameExists", "Account", "Username is already taken.")]
	public string UserName { get; set; }

	[Remote("EmailExists", "Account", "An account with this email address already exists.")]
	public string EmailAddress { get; set; }

	public string Password { get; set; }

In both of these instances of the Remote attribute, I’ve passed the following arguments:

  • The name of an action method;
  • The name of the controller where the action method lives; and
  • A default error message should user input fail this validation challenge.

2. Implement an action method to support your Remote attribute

You will need to implement an action method that supports your Remote attribute. Add an action method which returns a JsonResult to the controller you named in your Remote attribute arguments. In this example I’ll need to add these action methods to the “Account” controller:

public JsonResult UserNameExists(string username)
    var user = _repository.GetUserByName(username.Trim());
    return user == null ? 
		Json(true, JsonRequestBehavior.AllowGet) : 
		Json(string.Format("{0} is not available.", username),

public JsonResult EmailExists(string emailaddress)
    var user = _repository.GetUserByEmail(emailaddress.Trim());
    return user == null ?
		Json(true, JsonRequestBehavior.AllowGet) : 
			string.Format("an account for address {0} already exists.",
			emailaddress), JsonRequestBehavior.AllowGet);


If the repository returns null, meaning that a user account with this particular user name or email address doesn’t already exist, then we simply return a JsonResult with a value of true and go off on our merry way. This will suppress the jQuery validation library from raising a validation error.

If the action method returns false, then jQuery will raise a validation error and display the default error message provided in the Remote attribute arguments – if you didn’t provide a default error message yourself then the system will use an ambiguous default one.

If the action method returns a string, jQuery will raise a validation error and display the contents of the string, which is what I’m doing here in this example.

Small Gotcha – Naming Action Method Parameters

There’s one small gotcha that can be easy to miss – the name of the argument on your action method must match the name of your property on your model. If I changed the EmailExists body to look like this:

public JsonResult EmailExists(string email);

Then ASP.NET would pass a null value to this method.

Case 1: parameter name matches the name of the model’s property


Case 2: parameter name does not match the name of the model’s property


This is because the jQuery parameter takes the name of the property on the model and passes it as a querystring argument to your action method – here’s what your validation request looks like in Firebug:


The ASP.NET MVC model-binder isn’t all-knowing – it’s not going to be able to tell that EmailAddress and email are the same thing, thus it ultimately won’t bind an argument to your action method, hence why the null value is passed.

If you follow the convention of using a common name for your Remote validator action method arguments and your model properties, you won’t run into this issue.

UPDATE: Thanks to Rick Anderson for directing me to the much more extensive MSDN documentation on how to implement custom Remote validaiton in ASP.NET MVC3.

If you enjoyed this post, make sure you subscribe to my RSS feed!

LA .NET User Group ASP.NET MVC3 Lecture Notes

December 6, 2010 11:46 by Aaronontheweb in ASP.NET // Tags: , , , // Comments (3)

Putting this online for the benefit of the .NET LA User Group – this content is meant to accompany my talk on ASP.NET MVC3:

ASP.NET MVC3 links:

Source code:

PeerLearningSite on Github (Example Project with ASP.NET MVC3 RC)


Lastly, join the LA Windows Phone 7 Developers Group.

I’m going to put up some blog content to accompany this once my talk is done tonight – now I’ve got to go practice and give my talk :p

If you enjoyed this post, make sure you subscribe to my RSS feed!



My name is Aaron, I'm an entrepreneur and a .NET developer who develops web, cloud, and mobile applications.

I left Microsoft recently to start my own company, MarkedUp - we provide analytics for desktop developers, focusing initially on Windows 8 developers.

You can find me on Twitter or on Github!

Recent Comments

Comment RSS

Sign in