Safely Displaying Html Formatted User Content

Html escaping in ASP.NET MVC is a great way to prevent Cross-Site Scripting (XSS) attacks on your application.  The only problem I found was that sometimes an application needs to display formatted text and using the “Html.Encode(content)” will remove all formatting (as it is expected to).

So I have written a little extension method that enables specific html formatting to be allowed while still escaping potentally dangerous html.

public static class HtmlHelperExtensions
{
     private const string htmlTag = @"<{0}>";

     public static string HtmlEncode(this HtmlHelper helper, string text)
     {
          // encode the string
          string encodedText = HttpUtility.HtmlEncode(text);

          // put the text in a string builder
          StringBuilder formattedEncodedText = new StringBuilder(encodedText);

          // replace the escaped characters with the correct strings to allow formatting
          // <p>
          formattedEncodedText.Replace(string.Format(htmlTag, @"p"), @"<p>");
          // </p>
          formattedEncodedText.Replace(string.Format(htmlTag, @"/p"), @"</p>");

          // <strong>
          formattedEncodedText.Replace(string.Format(htmlTag, @"strong"), @"<strong>");
          // </strong>
          formattedEncodedText.Replace(string.Format(htmlTag, @"/strong"), @"</strong>");

          // <em>
          formattedEncodedText.Replace(string.Format(htmlTag, @"em"), @"<em>");
          // </em>
          formattedEncodedText.Replace(string.Format(htmlTag, @"/em"), @"<em>");

          // <span style="text-decoration:underline;">
          string underline = @"<span style="text-decoration: underline;">";
          string underlineReplacement = @"<span style=""text-decoration:underline;"">";
          formattedEncodedText.Replace(underline, underlineReplacement);

          // </span>
          // only find the spans that are related to the span for underlining
          var temp = formattedEncodedText.ToString();
          // for each instance of underline
          foreach (int i in temp.IndexOfAll(underlineReplacement))
          {
               // find the first instance of </span> after the underline span and replace
               var index = temp.IndexOf(string.Format(htmlTag, @"/span"), i);

               // delete the string at that location
               temp = temp.Remove(index, string.Format(htmlTag, @"/span").Length);

               // add in the new string at that location
               temp = temp.Insert(index, @"</span>");
          }

          formattedEncodedText = new StringBuilder(temp);

          // <ul>
          formattedEncodedText.Replace(string.Format(htmlTag, @"ul"), @"<ul>");
          // </ul>
          formattedEncodedText.Replace(string.Format(htmlTag, @"/ul"), @"</ul>");

          // <ol>
          formattedEncodedText.Replace(string.Format(htmlTag, @"ol"), @"<ol>");
          // </ol>
          formattedEncodedText.Replace(string.Format(htmlTag, @"/ol"), @"</ol>");

          // <li>
         formattedEncodedText.Replace(string.Format(htmlTag, @"li"), @"<li>");
         // </li>
         formattedEncodedText.Replace(string.Format(htmlTag, @"/li"), @"</li>");

         formattedEncodedText.Replace(@" ", @" ");

         return formattedEncodedText.ToString();
     }
}
Advertisements

One thought on “Safely Displaying Html Formatted User Content

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s