Preventing XSS Attacks and Using Html.Raw

I have a CMS system where I use CK Editor to enter data. Now if the user types <script>alert('This is a bad script, data');</script>

, then the CKEditor does a fair job and encodes it correctly and sends it &lt;script&gt;alert(&#39;This is a bad script, data&#39;)&lt;/script&gt;

to the server.

But if the user goes into the browser developer tools (using the Inspect element) and adds it inside it, as shown in the image below, then that happens when all the problems start. Now, coming back from the DB, when this is displayed in the browser, an alert box appears.

Edit CKEditor contents thru inspect element

So far I have tried many different things, one of them is

  • Encode content using AntiXssEncoder [ HttpUtility.HtmlEncode(Contents)

    ] and then store it in the database and when displayed in the browser decode it and display it with MvcHtmlString.Create [ MvcHtmlString.Create(HttpUtility.HtmlDecode(Contents))

    ] or Html.Raw [ Html.Raw(Contents)

    ] as you might expect both of them to display JavaScript warning.

I don't want to replace <script>

manually through code as it is not a comprehensive solution (search for "AND coded state:").

So far, I have referenced many articles (sorry not listing them here, but just adding a few as evidence to show that I made a sincere effort before writing this question), but none of them have code that shows the answer. Maybe there is a simple answer and I am not looking in the right direction or maybe it is not that easy and I might need something like Content Security Policy .

ASP.Net MVC Html.Raw with AntiXSS protection Is there a risk of using @ Html.Raw? http://blog.simontimms.com/2013/01/21/content-security-policy-for-asp-net-mvc/ http://blog.michaelckennedy.net/2012/10/15/understanding-text- encoding-in-asp-net-mvc /

To reproduce what I am saying, go to * this URL and in the text box enter <script>alert('This is a bad script, data');</script>

and click the button.

* This link is from Michael Kennedy's blog

+4


source to share


2 answers


It's not easy, and you probably don't want to. May I suggest you use a simpler language than HTML for user-formatted input? As for Markdown, which (I believe) is used by Stackoverflow . Or one of the existing Wiki or other lightweight markup languages ?

If you allow Html, I would suggest the following:

  • only supports a fixed subset of Html
  • after the user has submitted the content, parse the Html and filter it with a list of allowed tags and attributes.
  • be ruthless in filtering and eliminating anything you're not sure about.

There are existing tools and libraries that do this. I haven't used it, but I came across http://htmlpurifier.org/ . I guess there are many others. Rick Strahl posted one example for .NET, but I'm not sure if it's complete.

About ten years ago I tried to write my own whitelist. It parsed and normalized the injected Html. Then it removed any elements or attributes that were not included in the allowed whitelist. It worked really well, but you never know what vulnerabilities you missed. This project is long dead, but if I had to do this, I would use the existing simpler markup language, not Html.

There are so many ways for users to inject nasty things into your pages, you have to be brutal to prevent it. Even CSS can be used to inject executable expressions into your page, for example:



<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>

      

Here is a page listing known attacks that will keep you at night. If you cannot filter and prevent all of this, you are not prepared for untrusted users to publish formatted content that is accessible to the public.

While I was working on my own filter, MySpace (wow I'm old) was hit by an XSS worm known as Samy . Samy used styling attributes with an inline Url background that had a javascript payload. This is all explained by the author .

Note that your page says:

This page is for receiving and displaying raw HTML by a trusted editor.

Trust is the key issue here. If all of your users are trusted (say, website employees), then the risk is lower here. However, if you are building a forum or social network or dating site or anything that allows untrusted users to enter formatted content that will be viewable by others, you have a difficult task to sanitize the Html.

+3


source


I managed to solve this problem using the HtmlSanitizer in NuGet:

https://github.com/mganss/HtmlSanitizer

as recommended by the OWASP Foundation (as a good recommendation as I need it):

https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.236_-_Sanitize_HTML_Markup_with_a_Library_Designed_for_the_Job

First add the NuGet package:

> Install-Package HtmlSanitizer

      



Then I created an extension method to keep things simple:

using Ganss.XSS;

...

public static string RemoveHtmlXss(this string htmlIn, string baseUrl = null)
{
    if (htmlIn == null) return null;
    var sanitizer = new HtmlSanitizer();
    return sanitizer.Sanitize(htmlIn, baseUrl);
}

      

Then I check inside the controller when posting HTML:

var cleanHtml = model.DodgyHtml.RemoveHtmlXss();

      

And for the sake of completeness, sanitizing whenever you present it in a page, especially when using Html.Raw ():

<div>@Html.Raw(Model.NotSoSureHtml.RemoveHtmlXss())</div>

      

0


source







All Articles