Cross Site Scripting Attacks, abbreviated as XSS, is a variety of digital attacking where a user tricks a server into running some malicious JavaScript code when themselves, or another user, visits a page. This type of attack is very common, and typically occurs when a user has access to a text input on a web application.

XSS Attacks can be used for a variety of things; since the JavaScript executes in your browser, they have access to your local file system, and session information allowing for:

  • The installation of malware or adware on your browser or computer
  • Sniffing of your online session information, allowing them to impersonate you on that website
  • Performing some action on the website, which would seem as if you performed it (like changing your password)

These attacks are very powerful, however than can easily be thwarted. In its most simple form, you can mitigate leaving any XSS holes in your code by never allowing the user to enter data that is rendered as/in HTML. THIS INCLUDES URL PARAMETERS. I have seen quite few attacks happen because a URL parameter was not escaped before being output to the page. Just because the user isn't supposed to input something, doesn't mean they can't.

So - you find yourself staring at some code where the user's profile is output to the page. You test if you are open to an attack by entering "I really like <script>alert('BIG');</script> trucks" in the text area and hitting save. Boom, the word 'BIG' appears on screen in an alert when the page reloads, showing you your bio: "I really like  trucks". Time to close those XSS holes.

If there is no need for actual HTML tags to be present in your user's outputted data, pure PHP sanitation pre-output is the way to go:

htmlspecialchars($_GET['foo']), ENT_XHTML, 'UTF-8')

would convert all special characters that may allow the code to run, to harmless characters displayed on the screen. If you are dealing with text added to the page with JavaScript, utilize jQuery's text function, like so:

var safe = $('<span></span>').text(unsafe).html();

If you need the user's content to include actual HTML tags for formatting, and are not using a template engine, we recommend utilizing HTML Purifier to sanitize your code server-side before it is saved. Do not trust strip_tags, or a regex, as it is always possible to trick them with something like '<scr<script>ipt>'. If you are using a template engine, make sure that the saved data is outputted using some sanitation - TWIG does this by default, Smarty would utilize:

<p>{$foo|escape:'html','UTF-8'}</p>

Take care to review your code, and make sure you are not leaving your users, and your systems, vulnerable.