Cross Site Scripting (XSS) is an easy vulnerability to detect, but a difficult one to actually exploit.
If XSS is new to you, a good place to learn it is the XSS FAQ. Basically, in an XSS attack, the attacker is able to inject scripts to run on the victim's browser: these scripts could steal the session token, or any other data from the page.
How do we find if a page is potentially vulnerable to XSS? Well, we watch out for input parameters that get reflected to the output. Then, we check if those inputs accept script tags. The most popular (and simplistic) way of checking is to embed the following line into the input parameter that gets reflected:
If that alert window pops up when the output is rendered, the page is considered vulnerable to XSS.
Simple? Actually, the tough part has just begun.
Does the reflection of scripts in a parameter mean that the condition can be exploited meaningfully? When is the above condition a good candidate for an XSS attack? How do we test its exploitability?
For XSS to succeed, two conditions have to be met depending on how the script is to be embedded:
- If the script is to be embedded as application data in the html, then the output should be seen by a different user from the one who provided the input. A good example is a post in a bulletin board: the output is read by a user different from the one who made the input. This allows the attacker to inject malicious input that then gets rendered on the victim’s browser.
- If the script is to be embedded in a URL parameter, then the page the URL points to should not require authentication to access. Scripts embedded in URL parameters are typically exploited by sending an email to the user inviting him to click on it. But if the page it points to is an inner page that requires authentication to access, then the user will not be able to reach the inner page and the script will not execute.
The first case is the classical XSS that bulletin boards, chat rooms, and web mail are susceptible to. The second case is what one hopes to exploit in sites where the first condition is not met, ie. where input data from one user does not cross over as output to another user.
It turns out the vast majority of sites fall into the latter category - ecommerce apps, online banks, online reservation etc rarely have data from one user reaching another user.
And here is the bad news for attackers: even if condition 2 is met, and if a victim is fooled into clicking the link, the page they get access to will not contain any sensitive information like session tokens, or credit card. Why is that? Look at condition 2 closer: the page the URL points to should not be an authenticated page, to start with. Clearly, that page is a publicly accessible page and it's not likely to contain any sensitive data at that point. It would not even contain the session token for an authenticated session as the page was reached before authentication.
To paraphrase, XSS is an easy vulnerability to detect, but a very difficult one to exploit meaningfully.