Cross-Site Scripting (XSS)
One of the first restrictions placed on JavaScript in early browser versions was to build a wall around page content so that scripts executing within a frame served by one site could not access content of frames served by another site. Cross-site scripting, therefore, is an attack pattern that focuses on enabling scripts from one site (the attacker's site) to access content from another site (for instance, the user's bank account site).
To do this, users must typically visit either a malicious or naive website, although many experiments in social engineering have shown that users can be funneled toward even the most outlandish of sites quite readily.
The most common form of this type of vulnerability is a simple reflection flaw, and focuses on unfiltered HTML parameters (form parameters, typically) being reflected back to the user from a server request. The canonical form of this attack vector was first shown by search engine result pages, which typically reflected the user's query term in the title of the page. Without filtering, this reflected query term could easily contain HTML tags that were not correctly encoded and would therefore be interpreted as valid HTML by the receiving browser.
In essence, any reflection of unfiltered incoming data is a problem, as the number and variety of exploits resulting from XSS grows everyday; see Example 4.
public void doGet(HttpServletRequest req, HttpServletResponse res) { string title = req.getParameter("searchTerm"); res.getOutputStream().write(title.getBytes("UTF-8")); }
Just as the manifestation of XSS reflection is simple to describe, the mitigation is also incredibly simpleencode anything that is read from the incoming request before sending it back to the browser. While we're using Java here to show examples, all the prevalent page stacks include HTML encoding mechanisms that are easily employed to avoid this vulnerability. For example, this ASP statement is exploitable:
Response.Write Request.Form("username""
In contrast, the following statement is not:
Response.Write Server.HTMLEncode( Request.Form("username"))
Likewise, the same kind of transformation can be used in Java to prevent this exploit, although there's (still) no built-in object to perform a standard transformation. That said, it's simple to write such a String transformer. For those in search of an "off the shelf" package, the JTidy project (jtidy.sourceforge.net) is a good place to start.
Other, more complex, manifestations of XSS revolve around the persistent storage of unfiltered user input that is later used to provide response content. This is a more difficult type of XSS to diagnose, as the attack pattern depends not only on a user's unfiltered input being stored, but on that stored data being made available to other users from that point onward.
Naive forum software packages were particularly susceptible to this attack pattern in the early days of the Web. But even today, any application that stores incoming unfiltered data in a database (or file) and then sends that stored data to the user at a later date is vulnerable to this persistent form of XSS.
Once again, the mitigation is simple, requiring the program to either encode information before being stored or worst case to encode before sending information from the persistent store to the user. In general, it is always safer to encode data before storage, as in this way every possible future usage of that data is already guarded against XSS.
Finding the Flaws
Obviously, while the mitigations described here are simple to implement, the biggest challenge facing developers or development organizations trying to come to grips with security within an existing code base, or within code being newly created, is finding the areas of vulnerability. Manual code inspection can obviously be leveraged, but sitting around a table looking at reams of code, trying to find what might be extensively obfuscated vulnerabilities isn't anybody's idea of a fun time, I'm sure.
Static source-code analysis offers a potential solution to this problem, focusing on the potential vulnerabilities or weaknesses that are present in the code, rather than attempting to find existing exploits or attack vectors as a traditional application security or pen test dynamic tool might. Using an SCA tool can significantly shorten the time and effort involved in finding these issues and preparing them for mitigation.
There are many of these tools available with varying capabilities, both open source and commercial. Klocwork (the company I work for) provides one such commercial static source-code analysis product suite, focusing on C, C++, and Java, and providing developers fast, accurate analysis of operational defects and security vulnerabilities, integrated within your IDE of choice.