[RESOLVED]HTML Integrity in ASP.NET MVC

Hello ASP.NET Forums!!!! Once more, here I come to ask for your almighty help.  … :p  Hello!!! 

First of all, I am sorry if this goes to the HTML thread. I thought this was MVC’s because it’s a server-side problem. 

I have been learning about XSS (Cross-Site Scripting), HTML manipulation, and that I should treat my database as a fortress. Knowing that, I would like to know up to what level should I verify the user’s input. Let
me explain (please have some patience):

I’m doing a site that allows people to sell products to other people (clients) from a same repository. The vendor creates an account, and starts adding clients. Then, the vendor takes order from the client and process it through the application. 

Imagine I have the following Razor HTML:

        @foreach (var item in Model)
        {

            <div class="Product-Box" data-list-id="@(i + 1)" id="line-@i">
                <div class="Product-Box-Left">
                    <div class="Circular" style="background: url(@HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority)@Href("~/Content/Images/Products/" + item.Products.ProductCode + ".jpg"))"></div>
                </div>
                <div class="Product-Box-Center">
                    <span class="Product-Box-Center-Code">Code @item.Products.ProductCode</span>
                    <span class="Product-Box-Center-Name">@item.Products.ProductName</span>
                    <span class="Product-Box-Center-PV_BV text-center PV" data-pv="@item.Products.ProductDetails.PV">
                        <b>@((item.Products.ProductDetails.PV * item.Quantity).ToString())</b>
                        <br>
                        PV
                    </span>
                    <span class="Product-Box-Center-PV_BV text-center BV" data-bv="@item.Products.ProductDetails.BV">
                        <b>@((item.Products.ProductDetails.BV * item.Quantity).ToString())</b>
                        <br>
                        BV
                    </span>
                </div>
                <div class="Product-Box-Right text-center">
                    <p class="Product-Box-Price">
                    <p>
                        <span class="price" data-price="@ViewBag.Prices[i]">@((ViewBag.Prices[i] * item.Quantity).ToString())</span>
                        RD$
                    </p>
                    </p>
                    <p class="">
                        Quantity <span data-qt="@item.Quantity">@item.Quantity</span>
                        <input type="number" class="Quantity hidden" onchange="ChangeQuantity(@i,this.value);" value="@item.Quantity" min="1">
                        <a href="javascript:DeleteItem(@i);" class="remove hidden">Remove</a>
                    </p>
                </div>
                <input type="hidden" value="@item.ProductID" name="[@i].ProductID" data-val="true" data-val-required="The ScopeMode field is required." class="hiddenPI" />
                <input type="hidden" value="@item.Quantity" name="[@i].Quantity" class="hiddenQT" />
                <input type="hidden" value="@item.OrderModsID" name="[@i].OrderModsID" />
                <input type="hidden" value="@item.ClientID" name="[@i].ClientID" />
                
            </div>
            i++;


        }

It’s a form that processes the client’s order. The problem is that the form has hidden inputs in which I store the client’s ID, and Product ID (which are direct references to rows in the database a.k.a Foreign Keys).  This means that when the form is submitted,
so those values. Henceforth inserting them into the database will do the work of DB normalization.  

Sensitive information like the Client’s ID, are subject to verification tests to see if the Client’s ID correspond to the vendor, otherwise it throws an error. But… should I do the same to the Product’s ID and other
inputs which do not carry "personal-sensitive" information? 

That’s what is haunting me. Allowing the attacker to change the Product’s ID and other hidden forms will not affect the application security wise, but it would disrupt application flow only to the attacker (yes, only to the attacker). Like for example, changing
the Product’s ID hidden input to a value that is offset from the database or that does not exist. 

I hope I was clear enough. Thanks a lot in advance!

In my opinion you can send your product ID via hidden input, just make sure you verify properly and use the @Html.AntiforgeryToken() to protect your form post. When you collect values in your controller. do a lot of verification on all inputs that is most
important.

So, even if it couldn’t propose a security issue, should I verify it anyways? 

you should treat your controller actions as a public webapi, and supplied web pages just a handy tool to fill in the values for posting for novice users. so if product id are only valid by vendor, then you should validate the ids on the postback. you should
always validate on each request, the authenticated users access to key ids. 

if the client are tied to vendors then you should validate this relationship. you can often use database constraints for this.

if the client id is not a guid you should probably encrypt it before placing in a hidden field.

also assume someone has screen scraped your site, and is performing their own postbacks via their own application. there are generalized tools/websites for doing this.

Always verify and you can encrpt values in your hidden field which you would deencrypt when collecting in your controllers action method.

@Bruce: Thanks a lot. 

you should treat your controller actions as a public webapi, and supplied web pages just a handy tool to fill in the values for posting for novice users. so if product id are only valid by vendor, then you should validate the ids on the postback. you should always validate on each request, the authenticated users access to key ids. 

if the client are tied to vendors then you should validate this relationship. you can often use database constraints for this.

if the client id is not a guid you should probably encrypt it before placing in a hidden field.

also assume someone has screen scraped your site, and is performing their own postbacks via their own application. there are generalized tools/websites for doing this.

I didn’t know that web scrapping was the term applied for extracting information from a website. Thanks for letting me know that I need to check up the relationships between the clients and the users. I am already doing that, so it is good to know that I’m
on good track. What I didn’t catch is that if I need to verify if the product is indeed in the DB or not. 

And… YesI already have some helpers to help the user fill in the correct data. 

@skliz4rel: Thank you. I will be encrypting the information sent to the user, that way I can have a little bit more protection. Do you know which is the best method to do so?

Doing some quick Google yielded the following results, from StackOverflow:

http://stackoverflow.com/questions/14773148/how-to-encrypt-the-query-string-id-in-mvc4-actionlink/14774470#14774470 (Marked
Answer)

But then, I read this:

http://stackoverflow.com/a/15766560/1057052

Is this true for this occasion? Because I know that someone can spoof my connection, and can retrieve anything from the client side. 

Bwahahaha! Yes >:D (hahaha)

Thanks for teaching me the direction I should go. 

Reading this:

http://brockallen.com/2012/06/21/use-the-machinekey-api-to-protect-values-in-asp-net/

Sent me to these:

http://blogs.msdn.com/b/webdev/archive/2012/10/22/cryptographic-improvements-in-asp-net-4-5-pt-1.aspx

http://blogs.msdn.com/b/webdev/archive/2012/10/23/cryptographic-improvements-in-asp-net-4-5-pt-2.aspx

http://blogs.msdn.com/b/webdev/archive/2012/10/24/cryptographic-improvements-in-asp-net-4-5-pt-3.aspx

Which in other words, it means that yes, every data should be encrypted, and that should save me lots of problems. I will be only doing verification in the DB when sensible data matters (like Client and the vendor relationship, Order ID and the current vendor,
etc.).  Others I will not be doing them. 

Thank you all!!! :D :D 

Edit: 

Here we have the exact material:

public class StringProtector
{

    private const string Purpose = "Authentication Token";

    public string Protect(string unprotectedText)
    {
        var unprotectedBytes = Encoding.UTF8.GetBytes(unprotectedText);
        var protectedBytes = MachineKey.Protect(unprotectedBytes, Purpose);
        var protectedText = Convert.ToBase64String(protectedBytes);
        return protectedText;
    }

    public string Unprotect(string protectedText)
    {
        var protectedBytes = Convert.FromBase64String(protectedText);
        var unprotectedBytes = MachineKey.Unprotect(protectedBytes, Purpose);
        var unprotectedText = Encoding.UTF8.GetString(unprotectedBytes);
        return unprotectedText;
    }

}

Taken from:

http://stackoverflow.com/a/13362950/1057052

And here is another help:

http://stackoverflow.com/questions/16618120/how-to-use-machinekey-protect-for-a-cookie

Leave a Reply