Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MvcHtmlString.ToHtmlString() not encoding HTML?

Related to this question I play around with XSS issues in my ASP.NET MVC project and I´m confused with the MvcHtmlSTring.ToHtmlString() method. From the documentation "Returns an HTML-encoded string that represents the current object.", but it doesn´t work in my case:

    var mvcHtmlString = MvcHtmlString.Create("<SCRIPT/XSS SRC=\"htpp://ha.ckers.org/css.js\">").ToHtmlString();

    var encoded = HttpUtility.HtmlEncode("<SCRIPT/XSS SRC=\"htpp://ha.ckers.org/css.js\">");

Output of mvcHtmlString

<SCRIPT/XSS SRC="htpp://ha.ckers.org/css.js">

Output of encoded <-- this is the behaviour I would suspect!

&lt;SCRIPT/XSS SRC=&quot;htpp://ha.ckers.org/css.js&quot;&gt;

Did I miss something?

like image 405
Robert Muehsig Avatar asked Mar 21 '12 09:03

Robert Muehsig


2 Answers

MvcHtmlString (or HtmlString, or anything that implements IHtmlString) is for strings that should be emitted as HTML verbatim - i.e. by making that an MvcHtmlString you're telling it that you actually want those HTML tags.

The difference is when you emit the string into an ASP.NET page using <%: .. %> (new in ASP.NET 4 or later). In that case the ASP.NET engine will automatically HtmlEncode regular strings for you (or anything that doesn't implement IHtmlString) whereas the MvcHtmlString will be emitted into the page verbatim / unencoded.

i.e. I think the documentation is wrong. There's a connect ticket with the equivalent error in the HtmlString constructor documentation, which they did fix. (I thought I filed that :-/ maybe mine got closed as a duplicate of someone else's?) I didn't notice the MvcHtmlString documentation was wrong too.

like image 184
Rup Avatar answered Oct 06 '22 10:10

Rup


The MSDN documentation is correct, but perhaps a bit confusing. The MvcHtmlString and IHtmlString interface are used to represent a string that has already been HTML encoded. MSDN says:

Returns an HTML-encoded string that represents the current object.

The object you passed in to the MvcHtmlString object was already HTML-encoded, so both .ToString() and .ToHtmlString() merely return the object you passed in.

Please note that the MSDN docs do clearly state that:

The ToHtmlString and ToString methods return the same value.

So why have all this? Two reasons:

  1. In the Razor view engine and in ASP.NET Web Forms v4 an object that implements IHtmlString is written out as raw data. The view engines assume that the person creating the IHtmlString has already sanitized the data.
  2. The IHtmlString has its own stringify method so that it need not have the same implementation as ToString(). While ToHtmlString() must return the HTML, you could easily imagine that ToString() might return some developer-friendly debug information.
like image 36
Eilon Avatar answered Oct 06 '22 10:10

Eilon