I think cross site scripting has hit enough blogs and forums that developers are pretty aware of it, even if they're not entirely aware of every way the issue can emerge from their code. There are a lot of noble attempts to sanitise input to remove anything that might be interpreted as instructions for the browser, but Pratchett said it best with “Ninety percent of most magic merely consists of knowing one extra fact" which is all an attacker needs to have to thwart your defences.
It's starting to become understood that perfect defence of a system is not possible and all over infosec people are assuming compromise has occurred and putting their focus into detection and mitigation.
I think the new SQL injection is XPath injection, which seems to be becoming more popular and is basically a variation on the same concept.
A bit of background:
XPath is a query language for retrieving data from XML. XML to store login information might be structured like this:
So to check whether login input (the stuff you provide in the login form) matches anyone the site knows about, you might supply the following
"//user[name/text()='" + request.get("username") + "' And password/text()='" + request.get("password") + "']";
This looks at every user in the database and checks whether the user supplied input matches both the username and the password for any valid user. The addition symbols in this query concatenate terms, so what we wind up with is name/text()="whatever you supplied as username" and password/text()="whatever you gave as your password". Each of these will come back as either true or false depending on whether the supplied values match what's in the database.
"And" is a logical operator which makes the entire statement true only if both expressions are true.
You have a login form using this code to authenticate users. The user gives "Alice" as their username as "password123" as their password. This code will iterate through the database and come up "false" for every entry because none of them match. One of them has the right username but the password is different, so the query as a whole doesn't match. It's asking each of the entries on record whether name="Alice" AND password="password123"
However, if you supply this query with username "Whateveryoulike" and password "fakepassword' or 'a'='a" you automatically get in. This is because when you add this to the original query what you wind up with is:
//user[name/text()='Whateveryoulike' And password/text()='fakepassword' or 'a'='a'];
First it will check whether the username matches. It doesn't, so you've got FALSE AND password/text()='fakepassword' or 'a'='a'].
It's going to use a shortcut here and not check the password because it knows that the AND operator won't ever pass if one of the values is false, so that entire "username matches AND password matches" expression evaluates to false, so now we have:
FALSE OR 'a' = 'a'.
OR is another logical operator but this one will pass if either side evaluates to true. 'a' does equal 'a', so the expression as a whole passes. Essentially what you've done is injected your own query into the existing one and redefined the test for whether a user is valid or not to say that a user is valid if either of the following is true:
a) Username and password match
b) 'a' is the same as 'a'.
A lot of people assume that serialised data (data formatted to be easier to transport between systems, basically) is totally safe to work with and because XML is a fairly simple expression of data, they don't protect it as well as they would a more serious looking database.
XPath 2 is a less used but more modern standard which is actually advanced enough that you can inject into it instructions to open files on the server, which can lead to passwords to the machine being disclosed and the machine itself being totally compromised.
Tech stuff in this post got fairly heavy in some places, so I'm happy to go into things further if anyone wants.