Assignment: 00x03 XSS Filters - Build your own


I've foreseen a space on my FTP server where you can create your own labs. You are going to create them, hack them, and secure them before you learn what I mean by using the right filter for the right job.

Make a connection

Build an HTML tag injection lab

Add the following code to your file (If you have to make the file locally, add the copy and copy it onto the server).

<?php if(isset($_GET['fname'])){ echo $_GET['fname']; } ?> <form action="FILENAME.php"> <label for="fname">First name:</label><br> <input type="text" id="fname" name="fname" value="John"><br> <input type="submit" value="Submit"> </form>

Make sure to replace <form action="FILENAME.php"> with the name of your actual file.

Now hack it!!

Navigate to https://hackxpert.com/Training/YOURFILE.php

Replace YOURFILE.php with the name of your file. Make sure you uploaded it to FTP server. Now you can try to hack your own work.

Possible attack vectors

If you have not hacked the previous lab yet, stop reading here.

We can use any attack vector on this lab. <script>alert()</script> works here.

Let's secure it now

Whatever attack vector you used, we are going to filter it now. Replace the following line

echo $_GET['fname']; with

echo str_replace("script","",$_GET['fname']);

And upload the file to the FTP server.

This should remove any script instance so try <script>alert()</script> again. This will fail. The awake hacker has already spotted there are many ways to bypass this simple filter. Script would even bypass this.


We can add a bit more security by making sure the filter is applying a function to cast all characters to lowercase however, we will leave it here for now. We will come back on this later.

Let's change the context

So far, we've been trying to attack with a full HTML tag, however XSS can occur in much more than just 1 context. Right now, we are going to try and make a lab that expects you to inject XSS in the HTML tag attribute context.

Make a new file with the following content:

<?php if(isset($_GET['fname'])){ echo "<input value='" . $_GET['fname'] . "'>"; } ?>

<form action="FILENAME.php"> <label for="fname">First name:</label><br> <input type="text" id="fname" name="fname" value="Prof. Snape"><br> <input type="submit" value="Submit"> </form>

Where you make sure to replace FILENAME.php again. Upload it to the FTP server and navigate to it with the same URL: hackxpert.com/Training/FILENAME.php

Now hack it!

Can you find an XSS attack vector that works here? If you have not hacked the challenge yet, stop reading here.

Hack it

For this challenge, we can use any basic XSS as long as it breaks out of the HTML tag attribute, now I've tricked you 🙂

If you inspect the source code, you might see something like this:

This might prompt you to believe you need to enter " to break out of the attribute value since that's where the user input is reflected into. > should now break us out of the HTML tag:


Or does it...?

Let's check our code again!

That value does not seem encapsulated within double quotes (") but single (')

Sneaky rat 🙂

'>fdsfdsfdsfs will break us out the input tag

Now we can finalise it by inserting any HTML tag with a XSS attack vector.

'><img src=x onerror=alert()>

Now let's add another type of blacklist filter which makes it really hard to get any successful XSS to trigger:

<?php include 'instructions.php';

if(isset($_GET['fname'])){ echo htmlentities($_GET['fname']); } ?>

<form action="00.php"> <label for="fname">First name:</label><br> <input type="text" id="fname" name="fname" value="John"><br> <input type="submit" value="Submit"> </form>

The htmlentities function will stop most if not all XSS attacks. This is a replacement filter which will replace values it thinks are attacks in a similar way to a blacklist based filter, only we won't just remove the entries we deem to be an attack, we might have legitimate reasons for using <script> tags for example to showcase a piece of code and htmlentities will allow us to do so.

Let's add a whitelist

Make a new file on the FTP server and paste in the following code

<?php include 'instructions.php';

if(isset($_GET['fname'])){ $name = $_GET['fname']; if (!$name = filter_var($name, FILTER_VALIDATE_EMAIL)){ echo "Please enter an email address"; }else{ echo "Good!! $name"; } } ?>

<form action="50.php"> <label for="fname">First name:</label><br> <input type="text" id="fname" name="fname" value="John"><br> <input type="submit" value="Submit"> </form> <br> <br>

This lab is based on <a href=https://brutelogic.com.br/blog/xss-cheat-sheet/> Brutelogic's XSS Cheat sheet </a>

Make sure to replace the 50.php with the name of your file!

The section of code that is of interest here is:

if (!$name = filter_var($name, FILTER_VALIDATE_EMAIL)){ This whitelist filter will only allow email addresses to be passed, can you hack it?

Let's hack it!

If you have not hacked the challenge yet, stop reading here.

Inserting a valid email adress is not a problem and while it might seem pretty airtight at first, a closer look at the FILTER_VALIDATE_EMAIL filter will tell us that we can pass the following attack string as a possibly valid email.


2 types of filter, 2 types of XSS context

So far we have been able to implement a whitelist and blacklist and while both are valid option, none are ideal. Even the built-in PHP functions such as filter_var() can have bypasses and we should never rely on just 1 security mechanism. That being said, it was a lot harder to hack the last lab because of that whitelist validation. This might require some more resources but it has proven to be more secure and more resource intensive.

Besides the two types of filter, we can also distinguish between 2 context that our XSS got reflected into. These would be the HTML context (<script>alert()</script>) and the HTML tag attribute injection ('>) but I want you know there are a lot more. We will dive deeper into the JS context before we move on to the final DOM part.

JS context XSS

Let's make another file on the FTP server and fill it with this code:

<?php include 'instructions.php';

if(isset($_GET['fname'])){ echo "<script>document.write('" . $_GET['fname'] . "');</script>"; } ?>

<form action="40.php"> <label for="fname">First name:</label><br> <input type="text" id="fname" name="fname" value="John"><br> <input type="submit" value="Submit"> </form>

In here we can see some JS

document.write('" . $_GET['fname'] . "');

Make sure you replace 40.php with your filename.php

Can you navigate to the page you just made on hackxpert.com/Training/YOURFILE.php and hack it?

Let's hack it

If you have not hacked the challenge yet, stop reading here.

We can see a new script appearing on the page upon submitting a value This does a document.write('') We can break out with Solution: ');alert();//

Pay close attention to the ' single quote again as the same trick will be used here to make the attacker think they need to enter a double quote when they do not in reality.

DOM-what? DOM-where? DOM-here,there and everywhere?

as a last attack, we are going to make one final file. Add the following code:

Select your favourite cheese:


document.write("<OPTION value=1>"+decodeURIComponent(document.location.href.substring(document.location.href.indexOf("default=")+8))+"</OPTION>");

document.write("<OPTION value=2>Brie</OPTION>");

document.write("<OPTION value=3>Goude</OPTION>");

document.write("<OPTION value=4>Cheddar</OPTION>");


visit it via hackpert.com/Training/YOURFILE.php

Can you hack it?

A modern webpage consist of the source code (HTML, JS, CSS, ...) and the properties describing the webpage or document (such as URL, history, ...). Whenever a value goes into the Document Object Model or DOM from the source code via a DOM sink we can have a XSS attack. The DOM sinks are:








and the Jquery DOM sinks





















Please note we did not use JQuery in this challenge. The DOM sink in this case is:


or the document.location part to be specific. If we add the parameter "default" parameter to the URL, it will be reflected as the first option.


2 XSS Types, 3 Contexts and 2 ways of filtering and 2 types of filters: Conclusion

After all this we notice we can distinguish between DOM based XSS and SOURCE based XSS

We can also group stored and reflected XSS together but more on that in the stored XSS chapter.

We can group the XSS attacks into 3 contexts and more even, HTML, HTML tag attribute and JS.

We can notice filtering where we remove violations or where we disarm attacks.

We can note blacklist based or whitelist based filtering

All of these different aspects could determine the safety strategy of your application. I would recommend: