In our project in order to prevent XSS we added filter (HttpServletFilter) that simply escapes all occurrences of "<" and ">" in Json (wrapping user input) like:
json = json.replace("<", "<").replace(">", ">");
Question is: Is above enough to guarantee that XSS will never happen?
Or (in other words) can you provide example of user input that will cause XSS like behavior in our system?
Update: thanks to some useful answers, I understand that XSS still possible in case user input is used as source for href attribute or directly in javascript.
E.g. in case where triangle brackets already present on the their place around potential user input appearance.
But we never use user input data this way.
Any other suggestions?
Short answer: No, it's not enough
Please go read the OWASP XSS Prevention Cheat Sheet which explains the different contexts where XSS can occur.
No, you can not be sure. For example (from here):
<a href="{{anURL}}">
XSS Attack:
anURL = "javascript:alert(1)"
or
<script>var aPage = {{aVar}};</script>
XSS Attack:
aVar = "1;alert(1)"
You also could find some material from Microsoft or a sample implementation how to do it better on Github. A more detailled answered you may find on security.stackexchange.com.
Unfortunately It's not enough to escape triangle brackets. For example your site probably has some JavaScript code which deals with user input data. Someone could insert something malicious in a user input field and it would be executed directly by your JavaScript code. The malicious data would not need to contain triangle brackets because it is being injected straight into the JavaScript.
This old article is a good starting point. https://support.microsoft.com/en-us/kb/252985
Related
I'm working with HTML tags, and I need to interpret HTML documents. Here's what I need to achieve:
I have to recognize and remove HTML tags without removing the
original content.
I have to store the index of the previously existing markups.
So here's a example. Imagine that I have the following markup:
This <strong>is a</strong> message.
In this example, we have a String sequence with 35 characters, and markedup with strong tag. As we know, an HTML markup has a start and an end, and if we interpret the start and end markup as a sequence of characters, each also has a start and an end (a character index).
Again, in the previous example, the beggining index of the open/start tag is 5 (starts at index 0), and the end index is 13. The same logic goes to the close tag.
Now, once we remove the markup, we end up with the following:
This is a message.
The question:
How can I remember with this sequence the places where I could enter the markup again?
For example, once the markup has been removed, how do I know that I have to insert the opening tag in the X position/index, and the closing tag in the Y position/index... Like so:
This is a message.
5 9
index 5 = <strong>
index 9 = </strong>
I must remember that it is possible to find the following situation:
<a>T<b attribute="value">h<c>i<d>s</a> <g>i<h>s</h></g> </b>a</c> <e>t</e>e<f>s</d>t</f>.
I need to implement this in Java. I've figured out how to get the start and end index of each tag in a document. For this, I'm using regular expressions (Pattern and Matcher), but I still do not know how to insert the tags again properly (as described). I would like a working example (if possible). It does not have to be the best example (the best solution) in the world, but only that it works the right way for any kind of situation.
If anyone has not understood my question, please comment that I will do it better.
Thanks in advance.
EDIT
People in the comments are saying that I should not use regular expressions to work with HTML. I do not care to use or not regular expressions to solve this problem, I just want to solve it, no matter how (But of course, in the most appropriate way).
I mentioned that I'm using regular expressions, but I do not mind using another approach that presents the same solution. I read that a XML parser could be the solution. Is that correct? Is there an XML parser capable of doing all this what I need?
Again, Thanks in advance.
EDIT 2
I'm doing this edition now to explain the applicability of my problem (as asked). Well, before I start, I want to say that what I'm trying to do is something I've never done before, it's not something on my area, so it may not be the most appropriate way to do it. Anyway...
I'm developing a site where users are allowed to read content but can not edit it (edit or remove text). However, users can still mark/highlight excerpts (ranges) of the content present (with some stylization). This is the big summary.
Now the problem is how to do this (in Java). On the client side, for now, I was thinking of using TinyMCE to enable styling of content without text editing. I could save stylized text to a database, but this would take up a lot of space, since every client is allowed to do this, given that they are many clients. So if a client marks snippets of a paragraph, saving the paragraph back in the database for each client in the system is somewhat costly in terms of memory.
So I thought of just saving the range (indexes) of the markups made by users in a database. It is much easier to save just a few numbers than all the text with the styling required. In the case, for example, I could save a line / record in a table that says:
In X paragraph, from Y to Z index, the user P defined a ABC
stylization.
This would require a translation / conversion, from database to HTML, and HTML to database. Setting a converter can be easy (I guess), but I do not know how to get the indexes (following this logic). And then we stop again at the beginning of my question.
Just to make it clear:
If someone offers a solution that will cost money, such as a paid API, tool, or something similar, unfortunately this option is not feasible for me. I'm sorry :/
In a similar way, I know it would be ideal to do this processing with JavaScript (client-side). It turns out that I do not have a specialized JavaScript team, so this needs to be done on the server side (unfortunately), which is written in Java. I can only use a JavaScript solution if it is already ready, easy and quick to use. Would you know of any ready-made, easy-to-use library that can do it in a simple way? Does it exist?
You can't use a regular expression to parse HTML. See this question (which includes this rather epic answer as well as several other interesting answers) for more information, but HTML isn't a regular language because it has a recursive structure.
Any language that allows recursion isn't regular by definition, so you can't parse it with a regex.
Keep in mind that HTML is a context-free languages (or, at least, pretty close to context-free). See also the Chomsky hierarchy.
I have a problem where I am trying to cleanse the request content to strip out HTML and javascript if included in the input parameters.
This is basically to protect against XSS attacks and the ideal mechanism would be to validate input and encode the output but due to some restrictions I cannot work on the output end.
All I can do at this time is to try to cleanse the input through a filter. I am using ESAPI to canonicalize the input parameters and also using jsoup with the most restrictive Whitelist.none() option to strip all HTML.
This works as long as the malicious javascript is within some HTML tags but fails for a URL with javascript code without any HTML surrounding it, eg:
http://example.com/index.html?a=40&b=10&c='-prompt``-'
ends up showing an alert on the page. This is kind of what I am doing right now:
param = encoder.canonicalize(param, false, false);
param = Jsoup.clean(param, Whitelist.none());
So the question is:
Is there some way through which I can make sure that my input is stripped of all HTML and javascript code at the filter?
Should I throw in some regex validations but is there any regex that will take care of the cases that are getting past the check I have right now?
DISCLAIMER:
If output-escaping is not allowed in your internet-facing solution, you are in a NO-WIN SCENARIO. It's like antivirus on Windows: You'll be able to detect specific and known attacks, but you will be unable to detect or defend against unknown attacks. If your employer insists on this path, your due diligence is to make management aware of this fact and get their acceptance of the risks in writing. Every time I've confronted management with this, they've opted for the correct solution--output escaping.
================================================================
First off... watch out when using JSoup in any kind of a cleaning/filtering/input validation situation.
Upon receiving invalid HTML, like
<script>alert(1);
Jsoup will add in the missing </script> tag.
This means that if you're using Jsoup to "cleanse" HTML, it first transforms INVALID HTML into VALID HTML, before it begins processing.
So the question is: Is there some way through which I can make sure
that my input is stripped of all HTML and javascript code at the
filter? Should I throw in some regex validations but is there any
regex that will take care of the cases that are getting past the check
I have right now?
No. ESAPI and ESAPI's input validation is not appropriate for your use case because HTML is not a regular language and ESAPI's input for its validation are Regular Expressions. The fact is you cannot do what you ask:
Is there some way through which I can make sure that my input is
stripped of all HTML and javascript code at the filter?
And still have a functioning web application that requires user-defined HTML/JavaScript.
You can stack the deck in your favor a little bit: I would choose something like OWASP's HTML Sanitizer. and test your implementation against the XSS inputs listed here.
Many of those inputs are taken from OWASP's XSS Filter evasion cheat sheet, and will at least exercise your application against known attempts. But you will never be secure without output escaping.
===================UPDATE FROM COMMENTS==================
SO the use case is to try and block all html and javascript. My recommendation is to implement caja since it encapsulates HTML, CSS, and Javascript.
Javascript though is also difficult to manage from input validation, because like HTML, JavaScript is a non-regular language. Additionally, each browser has its own implementation that deviates in different ways from the ECMAScript spec. If you want to protect your input from being interpreted, this means you'd ideally have to have a parser for each browser family attempting to interpret user input in order to block it.
When all you've really got to do is make sure that the output is escaped. Sorry to beat a dead horse, but I have to stress that output escaping is 100x more important than rejecting user input. You want both, but if forced to choose one or the other, output escaping is less work overall.
In a Recent scan of our java based web application through AppScan it was found that the application was prone to XSS attacks.
I did my research and found that a ServletFilter was probably the easiest way to protect the application.
I introduced the filter where I extended HttpServletRequestWrapper (because java does not allow request param to be changed, there is no request.setParam method). I introduced a sanitize method there and here is what it does
result = ESAPI.encoder().canonicalize( input);
// Avoid null characters
result = result.replaceAll("\0", "");
// Clean out HTML
result = Jsoup.clean( result, Whitelist.none() );
Post this change, it was good, I tested for XSS vulnerabilites myself and most of them were fixed. But this posed another problem. Suppose I have a form to create a product, and in product name a user enters something like
<script>alert('somethingStupid')</script>
Now Ideally I should be able to save this to database, but still be protected from XSS attack. Not sure what to do in my filter or anywhere else to achieve this.
HTML-injection is an output-stage issue, caused by forgetting to encode text when injecting it into a context where characters are special. ESAPI offers encoders for various contexts, as discussed by #Zakaria. If you use these consistently, each in the correct context, you have fixed injection-related XSS issues.
If you are using purely JSTL tags like <c:out> for your templating, these will also HTML-escape by default. In general, it is best to generate HTML using a templating system that works HTML-escaping out for you automatically, because otherwise you are likely to forget to manually encodeForHTML occasionally.
(Aside: on project where I am compelled to use the mostly-terrible owasp-esapi-java library, my preference is for encodeForXML over the HTML encoders, as it produces output that is safe for HTML content and quoted attribute values whilst not needlessly attempting to produce entity references for non-ASCII characters. I would typically try to avoid injecting into JavaScript string literals; it is typically easier and more maintainable to inject run-time content into HTML data- attributes and read them from separate JavaScript DOM code.)
Trying to filter out HTML at the input stage is a lamentably still-popular but completely misguided approach. It prevents you from entering HTML-like input when you need to—as you have found out, with the <script> example. Indeed, if StackOverflow used such an input filter we would not be able to have this conversation.
What's more, it's not resilient: there are many ways to smuggle potential injections past input filters. To make a filter effective you'd have to consider blocking pretty much all punctuation, which is generally not considered acceptable. Plus, any data that gets into your application by means other than request parameters won't be vetted.
Input validation is great for enforcing business rules on the formats of particular input fields, and can be used to filter out input that you never want, like control characters. But it's the wrong place to be worrying about escaping or removing HTML. The time to do that is when you're creating HTML.
Cross Site Scripting (XSS) is a security issue which occurs when there is no mechanism of validating user input so the result will be an exploitable javascript code generally.
3 types of XSS are known : Reflexive XSS, DOM-based XSS and Persistant XSS.
In your case and since you're using OWASP ESAPI, canonicalizing inputs is not enough, sure it's a good way to defense against Untrusted URL in a SRC or HREF attribute but it's not enough.
You should Follow thess Rules : Source ( XSS (Cross Site Scripting) Prevention Cheat Sheet of OWASP ) (here are some rules for further reading follow the link) :
1- HTML Escape Before Inserting Untrusted Data into HTML Element Content: see the example :
String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );
2- Attribute Escape Before Inserting Untrusted Data into HTML Common Attributes :
String safe = ESAPI.encoder().encodeForHTMLAttribute( request.getParameter( "input" ) );
3- JavaScript Escape Before Inserting Untrusted Data into JavaScript Data Values:
String safe = ESAPI.encoder().encodeForJavaScript( request.getParameter( "input" ) );
I am passing directly a user defined parameter in my response header. Which I have learned is not a good idea since that way user can manipulate header and it can lead to Cross site scripting attacks and other kind of multiple attacks.
https://www.fortify.com/vulncat/en/vulncat/python/header_manipulation.html
What I am doing for preventing this is validate the user input for "http response splitting" by replacing "\r" and "\n" characters with empty string "". Is this enough or I have to check for other characters also. Any pointers would be of great help.
This is my code.
if(response != null)
{
newResponse = response.replaceAll("[\r\n]", "");
}
Is this enough for preventing this kind of attack or I should also validate for other characters.
A whitelist is much safer than a blacklist. Whether you can use a whitelist depends on how much you know about the user defined parameter.
More here:
http://cwe.mitre.org/data/definitions/113.html
The information you give is insufficient for a proper answer. We would need to know what you do with the parameter value in order to tell whether your actions are good enough or not and what kind of an environment your code runs in. A short, 100% correct (but pretty useless) answer would be "no."
Security is not implemented by following simple bullets taken outside of their original context. You took it from Python context and placed it directly to Java context. You must understand your environment and what your code does completely. There is no silver bullet.
I'm trying to filter out all possibilities of XSS from user name input while still allowing for foreign names to be inputted.
What is the best way to white-list all word-characters in multiple languages (also Chinese and Japanese and Russian)?
Is this possible at all? It would be easy to create a blacklist for XSS with "<>><" but then the hackers could work around this.
I think you may be approaching the problem from the wrong direction.
Typically, preventing XSS vulns is a case of ensuring that any user-generated content that you display on your website is properly escaped.
That way you ensure that what is displayed is exactly what the user entered, without having the risk of your whitelist inadvertently letting a few bad cases through.