Click here to Skip to main content
15,880,796 members
Articles / Security

Automatic Encryption of Secure Form Field Data

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
1 Jan 2013CPOL3 min read 41.1K   9   10
In this post, I will show you how to handle automatic encryption and decryption of hidden form fields using Rijndael.

Overview

My article on Throttling Requests got quite a bit of attention, so I thought I would continue the security theme and show you a simple method of automatically encrypting hidden form fields that you don't want the user to be able to change, or know the value of. I will be making use of an extension to the HtmlHelper, a custom ModelBinder to handle the decryption and also Rijndael encryption to secure your data (you could use any method of encryption you so desire).

I must stress that this is simply one measure to ensure the security of your data, you should always still be validating the action at the code and finally database level, to ensure you have a secure application!

Example

A really simple example of this would be on a CMS system, let's say user can only edit posts that they created. You may have something like this in your view:

ASP.NET
<%Using Html.BeginForm  %>
    <%:Html.HiddenFor(Function(m) m.DatabaseID)%>
    <!-- Other Editing fields here-->
    <input type="submit" value="Submit!" />
<%end using %>

If we inspected the code that is generated, we would get this:

VB.NET
<form action="/Home/Test" method="post">
    <input data-val="true" id="DatabaseID" name="DatabaseID" type="hidden" value="2012" />
    <input type="submit" value="Submit!" />
</form>

As you can quite clearly see, the database ID is 2012, and I could quite easily edit it to be able to submit against say, record 2013, which was posted by another user, if (God forbid) there was nothing checking in the back end that the user posting back actually has permissions to edit the post, you could malliciously edit other peoples data.

Rijndael

As I mentioned previously, I am going to be using Rijndael to handle my encryption, I'm not going to post all of the code here, you can use any encryption method you want, I personally grabbed this example, and made a few modifications to suit. Make sure you have a suitable encryption class in your project before you read past here!

Encryption

The first thing we want to do is create the part which handles encryption. We want to simply be able to replace the "HiddenFor()" with "EncryptedFor()". To do this, we need to create an HtmlHelper extension which accepts a Linq expression of the targeted field, so it works in much the same way as HiddenFor.

VB.NET
''' <summary>
''' Creates an encrypted version of the field
''' </summary>
<System.Runtime.CompilerServices.Extension> _
Public Function EncryptedFor(Of TModel, TProperty)(htmlHelper As HtmlHelper(Of TModel), _
expression As Expression(Of Func(Of TModel, TProperty))) As MvcHtmlString
    Dim name As String
    If TypeOf expression.Body Is MemberExpression Then
        name = DirectCast(expression.Body, MemberExpression).Member.Name
    Else
        Dim op = (CType(expression.Body, UnaryExpression).Operand)
        name = DirectCast(op, MemberExpression).Member.Name
    End If
    
    'Get the value, and then encrypt it
    Dim value = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)
    Dim encvalue = RijndaelSimple.Encrypt(value.Model, HttpContext.Current.User.Identity.Name)
    Return New MvcHtmlString("<input type=""hidden"" name=""" & name & "-encrypted"" value=""" & _
    encvalue & """>")
End Function

So now, if we go back to our form, we should be able to switch to EncryptedFor, which will generate the hidden field:

VB.NET
<form action="/Home/Test" method="post">
    <input type="hidden" name="DatabaseID-encrypted"
    value="3JSlRkRb98Ow11HkGRb1XQ==">
    <!-- Other Editing fields here-->
    <input type="submit" value="Submit!" />
</form>

As you can see, the field name has been appended with "-encrypted", and the value is the encrypted string.

Decryption

The next thing we need to do is to handle the decryption and setting of the value. The MVC model binder will obviously not know that the field "DatabaseID-encrypted" is actually for the field "DatabaseID". What we need to do is create a custom model binder, which looks for the field in the Request.Form, decrypts it, and then sets the property.

VB.NET
Public Class EncryptedModelBinder
    Inherits DefaultModelBinder

    Protected Overrides Sub BindProperty(controllerContext As ControllerContext, 
                                         bindingContext As ModelBindingContext, 
                                      propertyDescriptor As System.ComponentModel.PropertyDescriptor)

        If controllerContext.HttpContext.Request.Form_
        (propertyDescriptor.Name & "-encrypted") IsNot Nothing Then
            Dim decvalue = controllerContext.HttpContext.Request.Form_
            (propertyDescriptor.Name & "-encrypted")
            decvalue = RijndaelSimple.Decrypt(decvalue, "Some unique key")
            propertyDescriptor.SetValue(bindingContext.Model, _
            If(IsNumeric(decvalue), CInt(decvalue), decvalue))
        End If

        MyBase.BindProperty(controllerContext, bindingContext, propertyDescriptor)
    End Sub
End Class

We just need to register this in our Global.asax.vb file as well:

VB.NET
ModelBinders.Binders.DefaultBinder = New EncryptedModelBinder
And that's it!

The Result

I created a simple method which dumps out the request.form contents from the post back, and also outputs the value of the field. As you can see, the encrypted value was passed back, but the property has correctly been set!

Content of the request.form: 
DatabaseID-encrypted: SVwvHJ8kzCeIjIN4VZeJLw==

The DatabaseID on the model is set to: 2012

Conclusion

The aim of this post was to give you another tool to secure your websites, and that's all it is, a tool. You should secure your website every step of the way!

As usual, any questions, please leave a comment.

This article was originally posted at http://www.jambr.co.uk/Article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Hewlett Packard Enterprise Security Services
United Kingdom United Kingdom
Technical Architect for Hewlett-Packard Enterprise Security Service.

Please take the time to visit my site

Comments and Discussions

 
QuestionFeedback Pin
Nikola Mihajlov25-Sep-14 4:49
Nikola Mihajlov25-Sep-14 4:49 
QuestionA false sense of security actually creates a security hole Pin
Mike Lang2-Jan-13 3:56
Mike Lang2-Jan-13 3:56 
AnswerRe: A false sense of security actually creates a security hole Pin
Alexandre Jobin5-Jan-13 11:12
Alexandre Jobin5-Jan-13 11:12 
@Michael, what do you propose instead? I understand your point about creating a field DatabaseID to bypass everything. So what kind of solution can we use to secure some values in the form? If the user is authorized to only change is own records, we still need to put the id of the record to edit somewhere in the form. Maybe instead of putting "-encrypted" in the field id, we can decorate the property on the server backend with an attribute "EncryptedField"? Then, with a custom ModelBinder, if the property has the attribute, we decrypt the value passed.

Alex
GeneralRe: A false sense of security actually creates a security hole Pin
Mike Lang6-Jan-13 6:35
Mike Lang6-Jan-13 6:35 
GeneralRe: A false sense of security actually creates a security hole Pin
Karl Stoney6-Jan-13 6:46
Karl Stoney6-Jan-13 6:46 
GeneralRe: A false sense of security actually creates a security hole Pin
Mike Lang7-Jan-13 4:41
Mike Lang7-Jan-13 4:41 
GeneralRe: A false sense of security actually creates a security hole Pin
Karl Stoney7-Jan-13 22:05
Karl Stoney7-Jan-13 22:05 
GeneralRe: A false sense of security actually creates a security hole Pin
Nasir Razzaq17-Jan-13 0:22
Nasir Razzaq17-Jan-13 0:22 
GeneralRe: A false sense of security actually creates a security hole Pin
Mike Lang17-Jan-13 5:59
Mike Lang17-Jan-13 5:59 
AnswerRe: A false sense of security actually creates a security hole Pin
Karl Stoney5-Jan-13 11:36
Karl Stoney5-Jan-13 11:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.