secure-coding.com

SOS - Save Our Software

MVCSecurity code is now on codeplex

clock December 6, 2011 21:15 by author Administrator

Looking for my code to generate an encrypted form value in MVC to help prevent against form tampering?

It's on code plex now. It WILL ABSOLUTELY undergo future revisions that should be non-breaking changes.

http://mvcsecurity.codeplex.com/

 

The next changes will hopefully encrypt per a user specfic session so generate a more unique value that cannot be used in another user's session.



What's the use of hashing a password with a salt?

clock September 23, 2011 00:22 by author Administrator

First let's describe three main password storage themes.

1. Plain text

2. Encrypted

3. Hashed

#1 is obvious. It's nothing and the least secure where the password is stored without any modification. If an attack (or other browsing eyes) see this, the secret is gone, angels lose their wings, and children cry. It's like crossing the streams in GhostBusters. You just shouldn't do it.

#2 still stores a password in some format. The problem here is greatly mitigated as the password just can't simply be read. It has to go through some routine to encrypt it and another routine to decrypt it. If an attacker gets your data, they have to know what encryption method was used and what the encryption key is. Upon login, a user's password is encrypted and compared to the stored encrypted password or the stored password is decrypted and compared to the entered password. Either way it's relatively the same thing. Here an attacker can work on finding the decryption algorithm by performing an analysis on the encrypted data. The more data and the more known information the better. Thankfully, this technique is usually bypassed for easier targets because of the complexities in a good implementation of an encryption algorithm.

A no-no here is to store the key somewhere where an attacker can easily find it, such as in the database. An encrypted portion of your web.config may be a better place. See the blog entry on how to encrypt the data in your web.config file.

#3 takes your password and runs it through an algorithm to create a theoretically unreversible 'hash' of your password which is generally an alphanumeric string. You cannot 'decrypt' this. Upon login, the user's password they enter is hashed as well. This resulting hash is compared to the hash in the database. If they match - hooray! There is no password stored to decrypt. However, a weakness with hashes is that rainbow tables exist to help the attacker determine the password. A rainbow table is a precomputed huge table of hashes and the data for them. It's basically a database of hashes and the resulting plaintext used to create that hash. A password such as 'hello' may hash to 813HAB1C5914ED. The attacker simply needs to loook up 813HAB1C5914ED in the rainbow table and see it maps to 'hello' and the password is now known.

Enter in salts. A salt is an additional value added to your encryped or hashed value that specifies some random (or not random) sequence of bytes used an an input to your encryption or hash function. These bytes are readily available on the output hash so it may make you wonder whats the use of it, if its plainly available?

Well, without a hash, an attacker can pre-computer hashes/values with what's called a rainbow table. If you add some salt onto this, this means an attacker cannot use a pre-existing rainbow table to lookup what this hash value it. Your salt meants this new table would have to be completely regenerated which would take quite a while and quite a bit of computational power.

Thats the use of using a salt. IF someone steals your password hashes and they each use a different salt it means the attacker will have a whole lot of work on their end in generating new hashes to compare to your salted hash.



Welcome Tech Ed Attendees!

clock May 17, 2011 15:45 by author Adam Tuliper

If you attended my talk -at Tech Ed Atlanta - thanks and I hope you learned several things from it!

If you didn't please check it out online (link to be posted soon once it is up)

This site is _brand new_ and will hopefully be a great resource for you to secure your sites. If you have some great security ideas and would like to post here by all means contact me. We have a bunch of posts lined up for implementing security, protecting your site, configuring various membership providers and more!!

 



Helping to secure MVC forms from parameter manipulation

clock May 17, 2011 14:51 by author Adam Tuliper
Securing MVC forms from parameter manipulation



A common attack on web applications is parameter manipulation. This attack involves messing with some data - whether it's query string data, cookie data, form data, etc which then allows them to circumvent an assumed protection.
 
Let's take the scenario of someone editing their own User settings - password, address, etc.
 
Generally - some record/object identifier is emitted to the page. This could be done in web forms via something like
 
txtUserId.Text = user.UserId;
txtUserId.Visible=false;
 
When this is rendered, we will have roughly the following:
<input type="hidden" id="txtUserId" value="xxx" />
where "xxx" happens to be the primary key of the record that will be updated when the user posts back.

In MVC - this generally happens a lot more 'hidden' so to say. We generally would have code like such:

 
User user = UserRepository.GetUser(userId);
return View(user);

//where the user class is
public class User

{
        [HiddenInput(DisplayValue = false)]
         public int UserId { get; set; }
        [Required]
        public string UserName { get; set; }
        [Required]
        public string Password { get; set; }
}

In that case a field named UserId is rendered, basically the same as shown above as <input .... />

So - what happens if right before postback a user modifies this hidden form field and changes the UserId? They are then able to update a record that _isn't their_!!!!!

The smartest thing in this case to do is of course to make sure the user id 'belongs' to this user on the server side. If the user is trying to update a record they don't have access to, we throw an exception.

However these checks invariably get missed as a developer forgets to add this code in, or there was a refactoring that left it out, etc.

One solution web forms has - is if this data is tampered with on the client side for the hidden field, an exception will be throw because of EnableEventValidation=True

This is why you want to keep on EnableEventValidation=true and also EnableViewStateMac=true otherwise ViewState could be tampered with.
This creates a problem though for javascript that you intentionally want to change for ex. the selected value in a combo box (and add a new value) Web Forms will blow up on post back, as such developers often turn these protections off without understanding the risks. In the described case here you have to tell web forms what values you will be adding to the combo box although unfortunately we don't always know this.
 
In MVC , we have no such built in protections unfortunately. While it is true developers should ideally verify the data on the server side, I would venture to say it happens not as much as it should. Web Forms has built in validation - so why can't MVC!  It can, and I created a fine grained solution so you can specify exactly what values you want to check.
On our view, we call Html.AntiModelInjectionFor which is from the download at the end of this post.
 
@using Security_MVC.Extensions

..
..

@using (Html.BeginForm())
{

    @Html.AntiModelInjectionFor(o => o.UserId);

    @this.Html.AntiForgeryToken();

    @Html.EditorForModel();

    <input type="submit" value="Submit" />
 }
 
And on our controller
 
@using Security_MVC.Extensions


..
..

@using (Html.BeginForm())
{

    @Html.AntiModelInjectionFor(o => o.UserId);

    @this.Html.AntiForgeryToken();

    @Html.EditorForModel();

    <input type="submit" value="Submit" />
}
 


About the author

Something about the author

Month List

Page List

Sign in