How a Cross-Site Scripting Attack Works (and how to prevent it)

One of the most popular high-risk vulnerabilities plaguing websites today is cross-site scripting, or XSS. This kind of attack is popular because it is easy to perpetrate and, although it is easy to prevent, many websites were not designed with the necessary controls to do so. In this brief post, we describe how XSS works and how to prevent it.

Suppose we have a page with a simple web login form that features a text field for the user to enter her username and a password field for her to enter her password. Most users will come to this page and type their real user name and password. When they do and click the submit button, their entries are whisked away to a program running on the web server that checks whether the credentials they entered are legitimate. That server application responds by sending them either a page that gives them access to the site or a page that shows them an error message and gives them a chance to enter their information again. If the user did enter the wrong username or password, it is not uncommon for the ensuing page to show her the username she typed as a sort of sanity check. For example, the error page might say “Sorry. You entered the wrong username or password for user X.” Usually, “X” is innocuous: it is simply the mistyped username the visitor had entered.

Sometimes, though, a particularly devious soul visits the website and attempts to log in with a username that is actually Javascript code. Javascript, otherwise known by its official disease-sounding name Ecmascript, is by far today’s most popular language for commanding the browser to perform particular tasks. In other words, it’s a programming language your browser understands. If the visiting hacker entered some Javascript in the username field and then clicked the submit button, the Javascript they typed is moved through the Internet to the remote server. The remote server then, as usual, compares the username with the ones it has on file. In this case, it determines that, since no one’s actual user name contains Javascript code, the entered user name is invalid. So, it responds by sending a page that shows the user that she entered an invalid username or password. If that ensuing page is one that, as we discussed, tries to do the user a favor by showing her the erroneous username, then what will be sent back to the browser is the Javascript she entered in an effort to hack the site.

So why would this hack work? When a browser sees Javascript, instead of trying to render it as text on the screen, it actually tries to execute it. And therein lies the problem: if that Javascript the user had entered as a username and then gets returned to the browser was designed to do something bad, such as invoke a malicious link, download a virus, redirect you to a malware-ridden page, or steal data from your past interactions with the site, then you will have been the victim of a successful – and remarkably easy – attack.

Of course, the hacker won’t try to spring this attack on herself. Instead, she’ll embed it an email as a link for the recipient to click. This is called phishing. The hacker will include links that look legitimate based on their text, but the URL they direct to might include additional parameters – such as malicious Javascript code – that will pre-fill fields on the legitimate website, thus triggering the attack. Or, the link might lead to a different website entirely that, in turn, posts the malicious parameters to the targeted site. There are many ways to deliver the damage.

If you think XSS sounds like an easy attack to execute, you are correct. Fortunately, it is also easy to thwart. The task for any web application developer is to make sure that the server application that takes the user’s input and then responds with the code for the corresponding follow-up page never sends back executable Javascript the hacker might have entered. The task of making sure the back-end server keeps user-entered Javascript from returning back to the client’s web browser is called escaping. The funky symbols that typify Javascript statements are replaced with innocuous codes that the browser will simply pass through as text and not regard as statements to execute. The XSS attack cannot happen, because the Javascript payload could not be delivered as executable Javascript. Problem solved!

Interestingly, many of today’s most irksome and damaging attacks are relatively easy to fix. Developers today spend a lot of time going back and fixing these kinds of bugs they or their fellow developers missed the first time around. Some browsers, such as the latest versions of Chrome, can detect attempted XSS attacks and reject the incoming Javascript code instead of executing it.

Regardless, it is important that users not take such measures for granted. Never click on a link until you’ve hovered over it to see where it leads. If it looks like there’s some funky gibberish embedded in the link’s address, or if the link leads somewhere unfamiliar, don’t click!

About Ray Klump

Professor and chair of Mathematics and Computer Science Director, Master of Science in Information Security Lewis University http://online.lewisu.edu/ms-information-security.asp, http://online.lewisu.edu/resource/engineering-technology/articles.asp, http://cs.lewisu.edu. You can find him on Google+.

Leave a Reply

Your email address will not be published. Required fields are marked *