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.
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.
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.