How do you handle line breaks in HTML Encoded MVC view? - asp.net-mvc

I am unsure of the best way to handle this. In my index view I display a message that is contained in TempData["message"]. This allows me to display certain error or informational messages to the user when coming from another action (for example, if a user tries to enter the Edit action when they don't have access, it kicks them back to the Index with a message of "You are not authorized to edit this data").
Prior to displaying the message, I run Html.Encode(TempData["message"]). However, I have recently come into the issue where for longer messages I want to be able to separate the lines out via line breaks (<br>). Unfortunately (and obviously), the <br> gets encoded by Html.Encode so it doesn't cause an actual line break.
How do I process line breaks correctly in Html Encoded strings?

The easiest solution I've seen is:
#MvcHtmlString.Create(Html.Encode(TempData["message"]).Replace(Environment.NewLine, "<br />"))
If you are using a razor view, you should not have to call Html.Encode normally. By default, Razor html encodes all output. From Scott Gu's blog introducing Razor:
By default content emitted using a # block is automatically HTML encoded to better protect against XSS attack scenarios.

I agree with #Roger's comment - there is not really any need to encode anything that you have total control over.
If you still wish to be better safe than sorry (which isn't a bad thing), you could use the Microsoft AntiXss library and use the .GetSafeHtmlFragment(input) method - see HTML Sanitization in Anti-XSS Library
e.g.
<%= AntiXss.GetSafeHtmlFragment(TempData["message"]) %>

FYI, the Microsoft Web Protection Library (A.K.A. Microsoft AntiXSS Library) developers seem to have broken the assembly and pulled all previous versions that were working. It is no longer a viable solution in its current state. I was looking at it as a solution for this problem before reading the comments. All 18 of the current ratings for the latest release are negative and complain about it being broken with no updates from the developers so I didn't even try it.
I went with #ICodeForCoffee's solution since I'm using Razor. It is simple and seems to work quite well. I needed to take potentially lengthy descriptions with line breaks and format them so the line breaks would come through in the page.
Just for completeness, here's the code I used which is #ICodeForCoffee's code modified to use the description field of the view's model:
#MvcHtmlString.Create(Html.Encode(Model.Description).Replace(Environment.NewLine, "<br />"))

"Process" the message in the controller:
HTMLEncode the message
Insert the line break tags
Add message to the TempData collection.

Try this:
StringBuilder sb = new StringBuilder();
foreach(string message in messages)
{
sb.Append(string.Format("{0}<br />", Server.HtmlEncode(message));
}
TempData["message"] = sb.ToString();

Related

When do I need to encode with multiple codecs in Grails?

I'm not clear of when (or if) I should use multiple Grails encodeAsXXX calls.
This reference says you need to encodeAsURL and then encodeAsJavaScript: http://grailsrocks.com/blog/2013/4/19/can-i-pwn-your-grails-application
It also says you need to encodeAsURL and then encodeAsHTML, I don't understand why this is necessary in the case shown but not all the time?
Are there other cases I should me using multiple chained encoders?
If I'm rendering a URL to a HTML attribute should I encodeAsURL then encodeAsHTML?
If I'm rendering a URL to a JavaScript variable sent as part of a HTML document (via a SCRIPT element) should I encodeAsURL, encodeAsJavaScript then encodeAsHTML?
If I'm rendering a string to a JavaScript variable sent as part of a HTML document should I encodeAsJavaScript then encodeAsHTML?
The official docs - https://docs.grails.org/latest/guide/security.html - don't show any examples of multiple chained encoders.
I can't see how I can understand what to do here except by finding the source for all the encoders and looking at what they encode and what's valid on the receiving end - but I figure it shouldn't be that hard for a developer and there is probably something simple I'm missing or some instructions I haven't found.
FWIW, I think the encoders I'm talking about are these ones:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/JavaScriptUtils.html#javaScriptEscape-java.lang.String-
https://docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html#encode(java.lang.String,%20java.lang.String)
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/util/HtmlUtils.html#htmlEscape-java.lang.String-
.
It is certainly important to always consider XSS but in reading your question I think you are overestimating what you need to do. As long as you're using Grails 2.3 or higher and your grails.views.default.codec is set to html which it will be by default, everything rendered in your GSP with ${} will be escaped properly for you.
It is only when you are intentionally bypassing the escaping, such as if you need to get sanitized user input back into valid JavaScript within your GSP for some reason, that you would need to use the encodeAsXXX methods or similar.
I would argue (and the article makes a mention of this as well) that this should raise a smell anyway, as you probably should have that JavaScript encapsulated in a different file or TagLib where the escaping is handled.
Bottom line, use the encoding methods only if you are overriding the default HTML encoding, otherwise ${} handles it for you.

How to replace # in email address with <z>#</z> and not get < used instead

I am using Razor with MVC3 and ASP.NET4.5
I need to display jim#bloggs.com in a HTML email.
Due to issues with email clients adding mailto links to email addresses I need to alter them to prevent this happening. One recommendation is to add a non existent tag such as <z>. I have tried:
#(username.Replace("#","<z>#</z>"))
But this outputs:
jim<z>#</z>bloggs.com
How can I ensure I get the following in the HTML:
jim<z>#</z>bloggs.com
I suspect some tweak to :
#(username.Replace("#","<z>#</z>"))
is the answer. Thanks in advance.
You should use #Html.Raw() method, because string escaping is turned on by default in Razor.
#Html.Raw(username.Replace("#","<z>#</z>"))
Though there will be security considerations for this matter as it's a potentially XSS vulnerability, so you would better escape the initial value of the username at first and after that apply your tag insertion.

Struts 2 - is there any way to escape HTML in input fields?

When I allow a user to enter text using s:textfield, he can enter something like <b>Name</b> or something like \Me/. I want that these should be escaped before I am saving them to the database. When we retrieve them, the escaping is done automatically, but I want it to happen also when we are saving it.
I was trying to return a json output from my action class, but due to a name \a/ stored in my database, wrong json was being formed. This would have been avoided if the name had been escaped before being saved into the database.
You can use StringEscapeUtils. You can call escapeJavascript(textfield) in your action and then store it into the database.
#Daud, The problem you explained is called Cross site scripting or XSS.
And I think you should use Filters to clean the request parameters. This is the most sophisticated way. You can call these filters for the actions which are posting some parameters via request.
Visit my blog to see how to avoid XSS threat using Filter approach.
I also faced this issue when our project was tested by well known firm specializing in security testing and they suggested this filter approach.
You can give it a try.

Simple string templating in ASP.NET MVC

I have a bunch of database log messages containing references like Invoice 45 or Case 123 which I want to parse to output links to the appropriate invoice or case when displaying to the user.
These are fairly simple to parse with RegEx and replace with an action link using an ASCX display template, but is there a right way to do this? I imagine this means writing a parser to tokenise the string and prevent any potential circular references.
An HTML helper is probably a better fit - the parsing / display doesn't do anything that you could put in the ascx that isn't better handled in code.

ASP.NET MVC Url display problem

I have recently been experimenting with the profile features of ASP.NET. I am having trouble getting a "website" property to display correctly. For example, if the website I enter is: facebook.com/contactalig and I render it using
<%: Profile.Website %>
it gets rendered on screen as http://localhost:51225/users/facebook.com/contactalig Initially, I thought I might just prepend "http://" if it didn't contain one, but I feel there should be a cleaner solution.
Thanks in advance.
Without the protocol etc it isn't an absolute uri, so the browser (correctly) treats it as relative to the current URL.
So yes: check for a protocol. Perhaps just StartsWith is enough here, else a regex or maybe Uri.TryCreate (or whatever it is) specifying absolute-only.
Personally I would do this check at the point of data-entry, not at display.

Resources