MIME Type Custom Form Validator
I was recently working on methods to validate files uploaded by End Users and the usual recommendation of checking the file extension didn’t sit right with me, even more so when I found out that the .NET API ultimately just checks the File extension as well.
So the product a mornings work I’ve written a decent method of checking those upload files are what they say they are. In this case I created a Custom Sitecore WFFM Field Validator but its simple enough to port the code to custom web forms. Hopefully another dev will find this suitable as an alternative method.
As the FileUpload control is a Sitecore Webforms for Marketers Form I need to create a WFFM custom Validator (jump to the section below to skip the Sitecore set-up).
The custom validator is created by a class that implements FormCustomValidator and overriding the EvaludateIsValid method. Within that method we want to retrieve FileUpload control that holds the file we want to validate, confirm a file is present and then pass it to a function to complete the various stages of validation.
Configuring a new validator in Sitecore requires creating a new BaseValidator Item under the default path of /sitecore/system/Modules/Web Forms for Marketers/Settings/Validation. You will want to enter your the assembly and class into the fields of the same name as well as a error message for when the validator returns false.
Finally to add the validator to validate the appropriate field, navigate to the field, under the default path of /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types, find the Field Type Item, in the Validator field select your new validator.
Mime Type Detection
Now that we have the file from the FileUpload field we need to validate we can go ahead and make a Mime Detection utilities class.
The class contains byte array properties relating to each type of file; pdf, docx, gif etc. The main function accepts a byte array of the file and then compares the arrangement against the properties, returning the mime type when a match is made. File extension does have some limited use, but only to improve accuracy of similar file types.
Having completed the complex part we need to wire up the ValidateMimeType method to use our new MimeUtilities – reading the byte array in the stream before passing it to get the Mime type.
With the return value from the GetMimeType method it’s now time to determine if the file should be uploaded or not. This is easily achieved via checking the identified Mime type is present in a collection of permitted file types. In this example, the field should only allow images therefore I created a list property holding png, gif, jpeg etc. If the file is present the method returns true.
This could easily be extended to allow a Content Editor to define via Sitecore which File types are allowed per field.
That’s pretty much all you need to implement a more robust way of sniffing out what files your users are really uploading to your site and putting a stop to it! There are other logical steps you may want to implement – identification and limiting repeat uploads or implementing a file size limitation. An example of the latter is shown below.
File size check
And that’s it!
Pretty nice way of implementing security of uploaded files; sniffing out those MIME types and throwing away files we don’t want. There are a few good posts about using Byte Array Sequencing around the net if you wanna read more.