Learning security these days :)
I need to allow users to enter text in a form and allow them some HTML tags: bold, italic, list etc. and to prevent them to add some dangerous JavaScript code.
So I have used this whitelist implementation to sanitize HTML.
But I am still confused about how to save and display it in the right way.
So here what I did:
Model:
public class Post
{
[AllowHtml]
public string Data { get; set; }
}
Controller:
[HttpPost, ActionName("Create")]
[ValidateAntiForgeryToken]
public ActionResult Create(Post model)
{
// Decode model.Data as it is Encoded after post
string decodedString = HttpUtility.HtmlDecode(model.Data);
// Clean HTML
string sanitizedHtmlText = HtmlUtility.SanitizeHtml(decodedString);
string encoded = HttpUtility.HtmlEncode(sanitizedHtmlText);
View:
@using (Html.BeginForm("Create", "Home", FormMethod.Post)) {
@Html.AntiForgeryToken()
@Html.TextAreaFor(a=>a.Data)
<input type="submit" value="submit" />
}
So when I post a form I see:
<p>Simple <em><strong>whitelist</strong> </em>test:</p>
<ul>
<li>t1</li>
<li>t2</li>
</ul>
<p>Image:</p>
<p><img src="http://metro-portal.hr/img/repository/2010/06/medium/hijena_shutter.jpg" /></p>
Becaouse of <p><
I think that I need to decode it first:
<p>Simple <em><strong>whitelist</strong> </em>test:</p>
<ul>
<li>t1</li>
<li>t2</li>
</ul>
<p>Image:</p>
<p><img src="http://metro-portal.hr/img/repository/2010/06/medium/hijena_shutter.jpg" /></p>
Then I sanitize it against whitelist and I get sanitized HTML:
<p>Simple <em><strong>whitelist</strong> </em>test:</p>
<ul>
<li>t1</li>
<li>t2</li>
</ul>
<p>Image:</p>
<p>
1) Should I save it like this in database?
2) Or I need to Encode this result and then save it to database (encoded bellow)?
<p>Simple <em><strong>whitelist</strong> </em>test:</p>
<ul>
<li>t1</li>
<li>t2</li>
</ul>
<p>Image:</p>
<p>
Here I am confused if I put it on the view like this:
@Model.Data
I get this on the view:
<p>Simple <em><strong>whitelist</strong> </em>test:</p> <ul> <li>t1</li> <li>t2</li> </ul> <p>Image:</p> <p>
or
<p>Simple <em><strong>whitelist</strong> </em>test:</p> <ul> <li>t1</li> <li>t2</li> </ul> <p>Image:</p> <p>
So what to do to display this HTML properly (bold, list etc.)?
The rule of thumb is the following:
So:
[HttpPost, ActionName("Create")]
[ValidateAntiForgeryToken]
public ActionResult Create(Post model)
{
// store model.Data directly in your database without any cleaning or sanitizing
}
and then when displaying:
@Html.Raw(HtmlUtility.SanitizeHtml(Model.Data))
Notice how I used the Html.Raw helper here to ensure that you don't get double HTML encoded output. The HtmlUtility.SanitizeHtml
function should already take care of sanitizing the value and return a safe string that you could display in your view and it will not be further encoded. If on the other hand you used @HtmlUtility.SanitizeHtml(Model.Data)
, then the @
razor function would HTML encode the result of the SanitizeHtml
function which might not be what you are looking for.