简体   繁体   中英

Properly encoding/decoding a potentially dangerous form value in MVC3

I have a 'Description' field in a form. I would like the user to not be restricted from using special characters in this field.

As such, I would like to be able to POST the following data from my client to my server, save to the database, and be able to render properly again:

Test Description ( & &%$^&^() ^&&$& 87566467679089765 ?<>?<>?<>?<>":";';';'][][][][{}{}{}

I did some reading on the subject, but it seems like I have more options than I expected. I would like to make sure I do this properly for security's sake.

In my model, I've tagged my Description property with the AllowHtml attribute:

[DisplayFormat(ConvertEmptyStringToNull = false), AllowHtml]
public string Description { get; set; }

This allows the above data to POST to my Controller, but doesn't address the heart of the issue. I now believe I need to sanitize my input. I believe this means that I need to leverage the HttpUtility library.

Looking at HttpUtility, I see a ton of methods:

  • HtmlAttributeEncode
  • HtmlEncode
  • UrlEncode

According to this post there doesn't seem to be much difference between HtmlEncode and UrlEncode.

I'm wondering a few things:

  • Is using HttpUtility the correct choice here?
  • Is it fine to not do any processing of my input before POSTing? (Can I do all my encoding server-side?)
  • Should I be using Microsoft anti-xss libraries instead of HttpUtility?

and just generally any other pitfalls I might not have been made privvy.

UPDATE:

Here's my model:

<div class="detailsRow optional">
    <%= Html.LabelFor(model => model.Description, new { @class = "descriptionLabel" }, Model.DescriptionLabel)%>
    <%= Html.TextAreaFor(model=> model.Description) %>
</div>

and my controller method:

public ActionResult SaveNewOrderDetails(NewOrderDetailsModel orderDetailsModel)
{
    string description = orderDetailsModel.Description;
    //Successfully got description
    //Example code:
    Order order = new Order(description);
    order.Save();

    return Json(new { id = order.ID, name = order.Name });
}

after my code passes the 'return Json' statement, I am greeted with another error:

A potentially dangerous Request.Form value was detected from the client (Description="...>?<>?<>?<><?>":";';';'][][][][...").

My understanding is that this should not be occurring. Any places I should check?

UPDATE2 : Unable to get AllowHtml to work. I'm going to revisit this when we upgrade to MVC4.

I now believe I need to sanitize my input.

No, you are fine as far as receiving the user input and storing it into the database is concerned (assuming you have used parametrized queries which you should always do). The [AllowHtml] attribute will give you the possibility to enter any characters. If you wanted to sanitize the characters that the user could enter simply use a regular expression validator (I probably wouldn't bother with that):

[DisplayFormat(ConvertEmptyStringToNull = false)]
[AllowHtml]
[RegularExpression("PUT YOUR REGEX HERE")]
public string Description { get; set; }

You should be careful when you are rendering the value you have read from the database back to a view. You should make sure you always HTML encode it. For example the <%: function does that out of the box.

So here's a safe way to display it:

<div>
    <%: Model.Description  %>
</div>

Be careful to never do that:

<div>
    <%= Model.Description  %>
</div>

because this will not HTML encode the output and your site becomes vulnerable to XSS.

And here's another safe way using the DisplayFor helper:

<div>
    <%= Html.DisplayFor(x => x.Description) %>
</div>

Also if you want to render this in an editable field or text area simply use the corresponding helper:

<div>
    <%= Html.TextAreaFor(x => x.Description) %>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM