Well, here we are, in 2015, and most people (or at least the people likely to be reading this blog) have heard of Cross-Site Scripting (XSS) attacks by now. I hope so, at least, since this exploit has been well understood for at least fifteen years now.
What some (most?), but possibly not all of you may be aware of, is that XSS comes in two basic flavors (Or three, if you want to consider DOM-Based XSS as another basic type, but that is a topic for another time).
In “Persisted XSS” (sometimes “Stored XSS”), user supplied data is stored somewhere on the server-side of the application, usually in the database.
In “Reflected XSS” (the most ubiquitous kind), nothing is stored. User entered data is routed through the server and rendered back, to the exact same user, on a web page. Hence the term “reflected”. The server-side acts as kind of a data mirror, and “reflects” the trust the user has in the server and the domain.
For example, in PHP, Reflected XSS may look like this:
$myname = $_GET[‘myname’];
echo “Hello $myname, welcome back!”;
This code may be exploited by following a URL such as this one:
It doesn’t take a security virtuoso to see the problem with the first (“Persisted”) variety. Data entered by one user can alter the appearance, content, and behavior of a web page viewed by another user, in an unauthorized fashion. This is because the first user’s data is stored server-side, and potentially displayed to someone else. The second user (I’ll call them “the victim”, in case I need to blame them later) may be just another user, who can be thus tricked into doing evil things, or even an application administrator, who can be tricked into doing even eviler things.
It’s the second (“Reflected”) scenario that seems to throw some people off balance. That would include, in some cases, experienced security people. More than once, the following, seemingly simple and basic interview question has thrown security job candidates into rambling incoherence – which I love, because it makes me feel smart. But that’s not important right now. The question (doing my best Jerry Seinfeld here) is:
“So what’s the deal with Reflected Cross-Site Scripting anyway? The user sends in some bad data, and it comes right back to them. So, if they want to, they can hack themselves. Why should we care? Why do we cite this as a security vulnerability?”
I get all kinds of entertaining answers back.
So, here’s the real deal: An attack that exploits Cross-Site scripting is not a one hundred percent technical attack. It is at least partially a social engineering attack. It is not like SQL Injection, or a Buffer Overflow, where the trick is to discover the flaw and then fire off the right sequence of bits and bytes until the desired effect is achieved.
To make Cross-Site Scripting work, you have to fool a real person and get them to do something on your behalf. It is very much like phishing, with the presence of a technical flaw to assist in the intended deception.
Most Internet savvy people are aware of the problem of phishing sites. An attacker will make an exact copy of a legitimate website, for example, one belonging to the victim’s bank. They may be trying to entice the victim into filling out the login form and causing their user credentials to be sent back to the hacker.
Say the victim follows a link on a legitimate looking email and it takes them to what they think is their bank’s login page. How do they tell they are at a phishing site and not the real thing? Well, if the attacker has made a perfect replica, this can be tough. However, at the very least, the URL will be wrong. It will not match the bank’s proper domain. Attention to the domain in the address window will almost always reveal the deception.
Enter Reflected Cross-Site Scripting. If there is one of these flaws present on the bank’s actual site, the attacker can once again send that enticing email. However, this time, instead of linking to a bogus domain, the victim will be sent to the bank’s actual domain. Because of the flaw, at least a portion of the content seen by the victim there will have been produced by the attacker. How did this content get there? Well, the victim injected it of course (told you I would blame them!), when they followed the link on the attacker’s cleverly crafted phishing email. They have “hacked themselves”. The phishing email was the social engineering part of the hack. The technical flaw facilitated the seemingly legitimate nature of the page the victim landed on, by making it appear to originate from the bank’s domain.
I demonstrated this once for a very experienced developer who was fairly security savvy. I had just discovered a Reflected XSS flaw in his organization’s login interface, and wanted to walk him through it. He knew something was coming. I sent him a specially crafted email, with a link back to his own website, but with some disguised crafty stuff (designed to exploit a Reflected-XSS flaw) hidden in the query parameters.
I watched while he clicked on the link, and suspiciously examined the login page that appeared in his browser. He looked the whole thing over very carefully, and examined the URL. Nothing seemed amiss. “Yeah, I’d login to that” he finally admitted.
I encouraged him. “Try it. You knowwwww you want to ….”
So he did. I watched his face fall after he entered his credentials, pressed the button, and realized from the status bar messages that his credentials were actually being fired off to some server with my name in the domain.
So imagine this social engineering scenario: you discover a Reflected XSS vulnerability in an organization’s web application. You craft a link around this vulnerability designed to insert the BeEF hook code (by default a file named “hook.js”, but it could, of course, be renamed to anything) into the user’s browser when they click on the link. Then you send this link off to an application administrator. You may even get on the phone with this administrator, and complain “This link on your site is not working properly, I am getting strange results. Can you help me out?”
Guess what happens when the attacker hooks an administrator’s browser? They can now interact with the application as the administrator. This control may be tenuous and clumsy, and the attacker may sometimes have to perform actions in the blind, due to difficulties getting around the Same Origin Policy (SOP). But there is still the potential for great mischief, including setting up for a pivot to some other mode of attack. Note that an attack such as this could be pulled off even against an administrative interface that is not normally accessible from the public Internet.
So, if you’ve stuck it out and read this far – now you’re “in the know”. You’ll never be stumped by my very simple interview question. You’ll simply explain that a Reflected-XSS attack is a social engineering attack with a technical assist, and I’ll try to stump you with something else . . . because that makes me happy.
You can find the original article here.
Ken Malmquist is a Security Researcher at Astech Consulting. He is one of the most experienced application security engineers in the industry. He has reviewed literally millions of lines of code in various languages and helped developers understand and remediate source code vulnerabilities.