How to hack #2 – Cross Site Scripting


One of the most popular vectors of attacks on web applications is Cross-Site Scripting, called XSS. I will show you how the attack works and how to protect on some kinds of the attacks.

Why do you should be aware?

There are mostly three reasons why you should take care of it.

  1. Cookie theft – I will show a simple example in this article – the attacker will read the cookies from document.cookie variable and send it to a place where he can store it and get sensitive information like session id.
  2. Phishing – the attacker can modify the web page and, for example, show a fake login form.
  3. Keylogging – the attacker can attach to the addEventListener event and send all you type to his server. It is a very simple way to get passwords or credit card numbers.

How does it work?

The main goal of this kind of activity is to put the additional code on a page and execute it. In many cases, the code we want to add is a JavaScript script. Let’s start with a very simple example (written in PHP)

<?php header('X-XSS-Protection: 0'); ?>
    <link rel="stylesheet" href="" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  <div class="container">
  <form method="get">
    <h1>Submit the PRO form</h1>
    <label for="title">Title:</label> <input type="text" id="title" name="title" class="form-control" /> <br />
    <textarea name="content" class="form-control"></textarea> <br />
    <input type="submit" title="submit" class="btn-primary" />
  if (count($_GET)) {
    echo "<h2>{$_GET['title']}</h2>";
    echo "<div>{$_GET['content']}</div>";


INFO: I added the X-XSS-Protection header to the response disabling default browser’s XSS protection. We do need it now.

As you can see, we have a regular form. If the data are sent – display them. The problem is when we add some HTML/JS code and the code will be displayed without any filtering to other users. It is a standard XSS attack!

We have two ways to solve the problem. First of all – escape the problematic characters. In PHP world we have htmlspecialchars function which does the magic.

The second solution is removing the HTML tags completely. There is a function for that called strip_tags which is designed for this purpose. There is one problem with it: it is not 100% HTML safe what may cause some minor bugs. Take a look at the code above:

$tag = '">Here it is<img src=img.jpg';
<input type="text" value="<?=strip_tags($tag) ?>" />
the tag will be removed as we expected but the value of the input will be empty what’s not true

<input type="text" value="">Here it is" />
It may cause some other errors.

OK. It’s time for an example. I wrote working but a very ugly page in PHP which has no XSS protection.

header('X-XSS-Protection: 0');
define('cookie_name', 'user');
define('admin_username', 'pro_admin');
define('admin_password', 'veeerySecurePasswordGoesHere');
function isLoggedIn()
    return !empty($_COOKIE[cookie_name]);
function checkCredentials()
    if (@$_GET['username'] == admin_username && @$_GET['password'] == admin_password) {
        $cookie_value = "John Doe";
        setcookie(cookie_name, $cookie_value, time() + (86400 * 30), "/");
if (isLoggedIn()) :
        Search FBI database: <input type="text" name="search" value="<?=@$_GET['search'] ?>" />
else :
<h1>Some awesome login form</h1>
<form method="get">
            <td>Username: </td>
            <td><input type="text" name="username" value="<?=@$_GET['username'] ?>" /> </td>
            <td>Password: </td>
            <td><input type="password" name="password" value="<?=@$_GET['password'] ?>" /> </td>
            <td colspan="2"><input type="submit" value="Submit" /> </td>
<?php endif;


I did some very bad things here like muting PHP warnings or sending data via GET method but I want to keep the example as simple as possible so… please forgive me!

When you run the example on your local machine using, for example, built-in web server.

$ php -S localhost:8888

you’ll see a simple login form. When you enter credentials pro_admin/veeerySecurePasswordGoesHere you’ll see a search form to browse FBI secret database.

Let’s say you logged in. Someone wants to use your credentials and log in. The attacker knows there is a simple form with a field named “search” which is vulnerable. He can send a link to the victim and read his cookies data. The link may look similar to the above:


The example output will be

PHPSESSID=aeqcpdfcahs3n1o9it42dnbip5; user=John+Doe

And that’s all. You are hacked. You can enter the cookies to another browser or to a browser in incognito mode and you’ll see the secret FBI form. Nice, huh?!


This is only a simple example on how the attacks work and how this kind of vulnerable may be used. I hope you liked it.