Cross Site Scripting: what it is, and how to prevent it

Just think: you just created a browsergame. It’s taking off, and people are signing up by the truckload.

You’ve carefully made absolutely sure not to fall victim to SQL Injection, and your launch is going well.

But suddenly, something goes wrong. All of a sudden, users visiting the homepage are automatically getting redirected to nefariouswebsite.com!

What happened?

You’ve just become a victim of what’s known as a Cross Site Scripting attack(or XSS for short). Basically, a user enters some sort of malicious code(like some Javascript) into any area where user-input data will be displayed. It could be as simple as this:

<script type='text/javascript'>
window.location.href='http://google.com';
</script>

And the moment that that content gets displayed back to a user, their browser will see the <script> block and then redirect them. In this case, they would only be going to Google – but it’s easy enough to change the URL a user is getting redirected to to anything that you want.

How can you protect against this, if it’s a vulnerability that occurs in any situation where user-input data is displayed?

It’s actually a lot easier than you might have thought. All you need to do is escape all user input that will be displayed. And that means everything.

Do you display the user’s username anywhere? Even if it’s only ever displayed on that specific user’s profile page, you still need to escape it. Even if it’s only ever displayed to the user themselves.

Thankfully, PHP has a function custom-built to handle this – htmlentities(). Perl has a module that you can use to accomplish the same thing – HTML::Entities.

Now, you might be saying “that’s all fine and dandy, but what do I care? It doesn’t affect me if some users are getting redirected from some random page, deep within my site” – but there are multiple problems with that logic:

  • Attacks breed more attacks

Because it’s worked once, an attacker knows it will work again. So there’s no reason not to do it again – and not to do it in a more public place. Attackers perpetrating XSS attacks against sites will sometimes ‘practice’ in a quieter area of the site, so that the site administrators do not become aware of the exploit until it’s too late.

  • User frustration = no more users

Let’s say an XSS attack is executed against your site, and before you can fix it over 1000 users are redirected to nefariouswebsite.com – which just so happens to contain a malicious virus. That’s 1000 users who are never coming back and will never recommend your game ever again. And if you’re unlucky enough, there might be 25 among those 1000 that have decided it’s your fault for not securing your site adequately, and sue you.

Really, there are no gains to be made by not securing your game against XSS attacks. And it’s easy to implement – just make sure htmlentities() (or its equivalent, in your language of choice) is being called on any and all data you retrieve and display.

As long as you escape any and all data that you are going to be displaying to the user, you can avoid the risk of falling prey to an XSS attack. And no matter whether your browsergame is just getting started or already established, that’s always a good thing.