Avoid security risks when using RTE to send formatting? - asp.net-mvc

I'm using NicEdit for formatting texts in my ASP.NET MVC project, when I save the text, I get this error:
A potentially dangerous Request.Form value was detected from the
client (Body="<font size="6">text ...").
I understand the risk to post raw HTML, but is there a way to allow NicEdit to work without violating security rules?
Edit:
I put the attribute:[ValidateInput(false)] on the actions and used Html.Raw() in the views. Not sure if this is the best solution to take!

Related

XSS Attack prevention in C#

I've a Web API project which is consumed by an MVC project. The MVC project has a fair amount of user inputs which are displayed as output on the web page.
Now, I want to protect my site from XSS attacks. I've read about Microsoft's AntiXss library, input validations, output filtering etc. But my question is, How do I apply this to my project. Where to put input validations, how to filter my output, how do i sanitize user data, do I need to sanitize the data in APIs also or just in MVC before I send it to the APIs, and if yes, then how, where to use AntiXss library, in MVC or in web API, and how etc.
The answer depends on how exactly user input makes its way into the page DOM in the browser.
If the MVC application generates cshtml pages (with Razor), you need to implement output encoding there, in cshtml files. Note that AntiXSS as a separate library is now deprecated, it's now in the System.Web.Security.AntiXss namespace by default. You need to encode all output according to the context that they get written into (most importantly, you need to encode any input that's written in a Javascript context, be it a script tag, an event attribute like onclick, the first character of a href for an a tag, etc). For plain html output (text between tags) Razor already provides html encoding by default, so it's ok to just do <div>#myVar</div>.
If your frontend consumes something like a JSON API, then you probably have some kind of a client side template engine (Knockout, etc). In that case, it's reasonably safe to send data as received from the user back to the client with an application/json content type (that's actually very important). Then you have to carefully select binding methods to always bind user input as text and not as html to the page elements. This practically means things like using Knockout's text binding instead of html or using jQuery's .text() method instead of .html(), etc.
Please note that a full tutorial on XSS prevention would be way longer than an answer here, so this answer only highlights some high level things and the general way this should be done to prevent XSS.

Securely render arbitrary user-uploaded content (from a WSYWIG editor)

I have a site which allows an admin to edit a section of one page of the site with arbitrary HTML (via a WSYWIG editor), and I want to figure out a way to serve this arbitrary HTML securely to other users.
The basic intent is to eliminate any possibility of XSS errors (i.e, a user getting their cookie stolen or something).I've seen that the following subset of HTML tags are unsafe to allow users to enter: iframe, frame, embed, style, video, object, etc.However, filtering out iFrames or style tags is not feasible for my use case because admins need to be able to upload youtube videos and style the text.
I've also heard that Content Management Systems sometimes serve user-uploaded content from a separate domain (e.g, content.mysite.com) so that whatever code may run as a result of the user-uploaded content can't steal my site's cookie (e.g, app.mysite.com) because of the same origin policy.However, this seems like kind of an overblown solution for me since my site is not a CMS,there's just one part of one page (editable only by admins) which allows for arbitrary customization.
So, is there a way to go about this?Would embedding the arbitrary content in an iframe keep users safe? Thanks in advance!
Also of potential relevance: the framework I'm using is Ruby on Rails.
An html editor on the client is not straightforward to protect against XSS at all. As you say, serving such content from a different domain may mitigate the risk, but gives way to other questions (like for example how will you authenticate and authorize users on the other domain to prevent downloading any user's content).
Also whitelist validation of tags and attributes is usually not feasible. You could have a whitelist of tags and attributes of those tags and anything else could be removed from html code. The problem with this is that the html editor will most likely want to use the style attribute, and styles are vulnerable to XSS, at least in older browsers. An editor usually needs to be able to save a link (<a href="">), and that's also vulnerable to XSS, for example <a href="javascript: alert(1)">.
One approach you may take and one that actually works is Google Caja. It can remove all Javascript from HTML, Javascript and CSS so that it's safe to include in your page. It also has a client-side sanitizer written in Javascript that can be used by itself, and may provide enough protection. Another client-side sanitizer is DOMPurify. Caja at its best is a server-side solution too, but that's somewhat harder to install and maintain. The client-side part of it, and also DOMPurify are slightly less secure as they are all on the client, but can very well provide adequate protection in many situations. (Note that DOMPurify does not work in older browsers and does not sanitize CSS code, which is OK-ish for recent browsers.)
With these client-side solutions, you let the user save any HTML with any injected Javascript to the database if the user (attacker) is smart enough, but when displaying the html content, you send it to the client in a way that's not vulnerable to XSS (like for example in an AJAX response with a text/javascript content type), and then run it through the client-side sanitizer in the browser before inserting into the page DOM (giving it to the editor control itself).
If your editor allows for the right hooks, you can also do this for any preview functionality, sanitizing the HTML entered before switching to preview. This is important, because while arguably a smaller risk, it is still considered XSS if the user can inject Javascript in the editor and then run it in preview, without ever sending it to the server. This is called DOM XSS, and it is one reason you may want to do sanitization on the client.

Client/Server Validate Common Data Types (e-mail address) with ASP.NET MVC

What is the preferred method (one that has minimal custom code and ideally is portable to planned future versions of MVC without extra widgets) to validate common datatypes (e.g. e-mail addresses, dates, phone numbers) at both the client and server?
MY RESEARCH
I'm going to list a few methods I've seen, approximately from worst to best (IMHO). I'm currently using the last method listed. I'll focus on e-mail validation in this post, to keep things clear.
REGEX AND/OR CUSTOM VALIDATION ATTRIBUTE
I know jQuery validate includes some common datatypes including e-mail, and additional plugins exist for download (e.g. integer, max words). So custom regex's here are not the right answer.
I know how to write a custom validator from scratch at server and client, and even to 'adapt' an existing client-side rule to a custom attribute when using the unobtrusive connector. http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html
but it probably doesn't make sense for such a common type as e-mail address.
Nor, probably, to extend a regex rule, as per:
http://www.pagedesigners.co.nz/2011/02/asp-net-mvc-3-email-validation-with-unobtrusive-jquery-validation/
OVERRIDING STOCK DataType ATTRIBUTE VALIDATORS
.NET includes [System.ComponentModel.DataAnnotations.DataType(DataType.EmailAddress)]
This causes always-succeed validation at client or server, and is really only useful out-of-the-box for a tangential purpose of formatting display strings. Overriding the always-succeed validation is possible, as per:
http://weblogs.asp.net/srkirkland/archive/2011/02/15/adding-client-validation-to-dataannotations-datatype-attribute.aspx
MVC DATA VALIDATION EXTENSION (VIA NUGET)
A NuGet-downloadable validation extension was released several months ago, and I'm currently using it, but I was surprised to see that it did not leverage the existing DataAnnotations.DataType enum. It makes me wonder if there is some development divergence that I should be avoiding here.
http://weblogs.asp.net/srkirkland/archive/2011/02/23/introducing-data-annotations-extensions.aspx
Also, it doesn't include phone numbers or US phone numbers.
Any better method?
Have you know about ASP.NET MVC 3 Futures Validation attributes,
http://weblogs.asp.net/imranbaloch/archive/2011/02/05/new-validation-attributes-in-asp-net-mvc-3-future.aspx

WMD editor sanitizing

I am trying to find ways to sanitize the input of the WMD editor.
Specifically, I am trying to make HTML tags only available in the <code>tags that WMD generates. Is that possible
My problem is that the following code is rendered as HTML which is vunerable to potential XSS attacks.
For example, <a onmouseover="alert(1)" href="#">read this!</a>
The above code renders normally both in preview mode and when saved to the database.
I notice that Stack Overflow doesn't seem to have this problem. The same code is just rendered as text.
I notice that the Stack Overflow team has shared their code in http://refactormycode.com/codes/333-sanitize-html. Do I really have to use C# in order to sanitize WMD to do this?
I ended up using HTML Purifier for this.
If you want to block bad scripts from WMD on the client side, take a look at my answer here:
Align the WMD editor's preview HTML with server-side HTML validation (e.g. no embedded JavaScript code).
It shows how to implement a client-side whitelist in the WMD editor to restrict WMD's preview pane HTML to known-safe HTML elements and known-safe HTML attributes. It does the validation after WMD geneates its HTML, so even if there's a bug in the WMD editor's HTML generation which allows bad script to get through, the whitelist blocker will catch it. This code is based on StackOverflow.com's implementation of the same validation.
That said, you also need server-side validation too (If you're using PHP, HTML Purifier is a good choice), because even if you fix the client, that doesn't prevent an attacker from simulating a browser and saving malicious markdown by POST-ing it to your server. So doing client-side WMD previewer validation isn't actually required, except to defend against an obscure case where an attacker manages to get compromised markdown onto the server, and convinces a site moderator to edit the page. In that case, client WMD previewer validation might prevent an attacker from taking over the entire site.
Also, doing client-side validation can be helpful because then you know that the same tags and HTML allowed by the client will also be allowed on the server. Make sure to sync the server-side whitelist with the client whitelist. StackOverflow's whitelist is here if you want an example.

Handling Rich Text in an MVC application

What are the best practices regarding working with rich text in a web application? I don't want to leave myself vulnerable to script attacks. Should the data be encoded going into the database and then decoded when displayed back to the user? Any advice on rich text editor's that handle things like removing script tags or encoding the entered markup?
You should pick a whitelist of known tags and attributes, parse the user input as XML, and remove every tag or attribute that isn't in the whitelist.
EDIT: Note that if you allow hyperlinks or images, you have to validate the src and href tags. I would recommend parsing it using System.Uri, restricting the scheme to http, and perhaps the domain to your site (depending what you want your users to be able to do).
Similar things have been done before; google them.
EDIT: For example, see this question
2nd EDIT:
You should not encode the data before putting it into the database. As long as you're using parameters (and if you aren't, you really should), the database will be completely unaffected by anything you put in it.
If your input sanitization is secure (see above), it won't make any difference if you encode it and decode it on the way, and if the sanitization isn't secure, encoding it won't help.
However, it probably is a good idea to run it through a standard XML parser, reject any input that doesn't parse, and use the formatted XML from the parser (as I mentioned above)
3rd EDIT:
There are many rich text editors out there; for MVC, I think I'd recommend FCKEditor. It will escape input for you, but you must not rely on it exclusively as an attacker can disable JavaScript or forge his own HTTP request. (You still need to validate the HTML on the server). There are many rich editors for web forms (which, I assume, do server-side validation); there aren't any for MVC (yet)
The best option is to encode data which is send to user and do not encode it in database.Also far as I know asp.net prevent script attacks by validating input.

Resources