Year Of Security for Java – Week 37 – Solve Cross-Site Scripting

No Gravatar

What is it and why should I care?
Cross-Site Scripting (XSS) is another issue that is caused because of poor code/data separation. The general issue is that a developer intends the user input to be interpreted as data, but an attacker can manipulate the input to cause the browser to interpret the input as tags or commands.

XSS is exceedingly popular and well-known, and along with SQLi, is probably 1 of the 2 best-known vulnerabilities across web app security.

What should I do about it?
Note: One great resource which I drew from for both this post as well as the more in-depth post is the XSS Prevention Cheat Sheet over at OWASP.

I’ve already written here on the problems with and solutions for XSS. However, I’ll cover the basic solutions briefly here for clarity’s sake.

1. Canonicalize Input
Get your input data into it’s simplest base form in preparation for validation so that you’re more confident your validation routines aren’t being circumvented.

2. Validate Input Using a Whitelist
Whitelist validation (accept only known good data) is a key tenet of good security. Check the content of the data, the length, data type, etc.

3. Contextual Output Encoding/Escaping
Output Escaping is the last step, and must be done for the appropriate context. You must understand where you’re sticking data, and how that location is interpreted from the browser’s view. This can be a sticky issue, so this one gets a bit problematic.

Now that we’ve covered the basic technology solution for XSS, let’s consider the larger context of eradicating entire classes of vulnerabilities from our codebase as I discussed a couple weeks ago. Let’s look at each specific subpoint I mentioned in that post and consider what you might do regarding XSS.

1. Understand the problem.
I’d read available documentation on XSS to make sure I understood the issue as well as I *think* I do. The cheat sheets at OWASP are good for basic theory, but there are books that talk about the issue in more detail, and there are additionally books that discuss how browsers work that can be helpful to understand. XSS is actually one of the more complex vulnerabilities around, and it actually is still changing because it’s so closely tied to browser feature sets which are always expanding. In addition, javascript frameworks of significant capability have had a huge impact on web applications in the last 5-7 years, thereby compounding the problem.

2. Consider all use cases where the issue can occur.
I would think about all the different types of XSS interactions that occur in my application portfolio. How many languages am I developing in or supporting? What frameworks am I developing with? Do I need to allow users to enter HTML that is then displayed (JSoup / AntiSamy problem space)? Do I have a constrained browser environment (or do I still need to support IE 6)?

3. Evaluate solutions.
I would look at the XSS cheat sheet from OWASP (and any associated weaknesses with the approaches that it espouses). Once I understood the recommended solution(s), I would consider whether said solution(s) would work in the environment in which I’m working. For XSS, there’s really not a lot of alternatives to how to solve the basic problem. However, there are differing implementations of solutions. For example, there are solutions where that require more effort to solve the issue, but do leave the maximum of flexibility (plain ol’ JSP’s), there are frameworks that default to solving the most common version of the problem (struts, springmvc, etc. – all default to basic html entity encoding), all the way up to templating solutions which constrain flexibility but offer a safer-by-default scenario (JXT). Consider also solutions for special use cases, such as the requirement to allow certain constrained amounts of HTML along with plain data, and how you might solve that class of issue (JSoup / AntiSamy).

4. Institutionalize the chosen solution.
After deciding on your collective solution, you have to work with development teams to determine the current status of vulnerability to XSS (beware: it’s probably gonna be pretty bad). This step is a good place to (re)train developers on this specific topic from a security perspective, since they’ll be implementing the solution. You then just have to do the work of implementing the chosen framework(s), making necessary modifications to the source, and re-testing applications to make sure everything still works as expected.

5. Add technology and processes for verification.
At this point, I would add a few tools in to make sure the technology is being used. I would make sure that there were static and dynamic analysis tools in place to check for XSS, though tools vary in usefulness here and coverage can sometimes be spotty. I would also make sure to code review UIs to see where dynamic data is emitted. I might go so far as to write custom rules for my static toolset that “trusts” my safe output functions to reduce any false positives. Lastly, I would specifically look for “known bad data”. Using something like AppSensor or a WAF is a way to automate some of that process.

In conclusion, hopefully it’s clear that solving XSS is a manageable task, but just takes some focused effort on research, training, implementation and verification. The pattern I’ve described for both SQLi and XSS are useful to follow for other vulnerability classes in order to really build a robust environment and suite of applications.


Be Sociable, Share!

Technorati Tags: , ,