Identifying Cross-Site Scripting Within A Web Application

When testing for Cross-Site Scripting vulnerabilities prior permission should always be obtained, this can either be through penetration testing rules of engagement or a bug bounty program. Multiple bug bounty programs exist and enable users to test for vulnerabilities on real-world targets. Any vulnerabilities or “bugs” found can be responsibly reported for a reward.

Some bug bounty programs are;

To progress through this article, it’s recommended you have a rudimentary understanding of how and why Cross-Site Scripting occurs, to help with this you can always check out our Introduction To Cross-Site Scripting.

A Brief Introduction To Burp Suite

The only tool required to test for Cross-Site Scripting is a modern web browser such as Chrome or Firefox. However, it is recommended that you take a look at Burp Suite.

Burp Suite is a dedicated tool for testing web applications, it comes with several useful features including a proxy, encoder/decoder, built-in browser and site map along with much more. Best of all, a free community edition is available.

Although the community edition isn’t as feature-rich as the premium version, it still includes several useful tools that can aid in our testing.

Performing Application Tests

Assuming you’ve gone down the route of downloading and installing Burp Suite, the built-in browser will enable you to browse the target website. Any links should be visited and any input fields completed and submitted, this allows for Burp to build a full map and browsing history of the application.

For each input field and URI parameter found, a simple test phrase should be entered, this should be something which does not already exist within the application. I’d recommend something fairly random such as t3sTXSS. Once the input field has been submitted or the URI visited, the page source code can then be examined, this can either be done by right-clicking and selecting “View Page Source” or pressing Ctrl+U. If using Burp then the response source code can be seen on the Proxy > HTTP History log. Using the find feature combined with the test phrase, it’ll locate any areas where the input is reflected.

If the provided phrase can be seen, it’s now recommended that special characters are tested, this will enable us to determine whether the application has any filtering enabled which would prevent any Cross-Site Scripting payloads from being executed. The usual characters which are included with Cross-Site Scripting are < > ” ‘ { } ( ) ;, however, other characters could also be required.

Using Burp, the HTTP history item for the field you’re testing can be sent to the Repeater. The Repeater allows for the same HTTP request to be repeated, hence the name. However, what makes this so great is that the user can make changes to the request before it’s sent, this will streamline the process of testing various special characters and payloads.

Now that your understanding of the application has been expanded, it’s time to start testing potential payloads. Each application is different and will handle input differently. With each payload you’ll need to inspect the application source to see if any characters are being filtered, you’ll likely need to modify any existing payloads to have some success.

Here are some common payloads which are used to test for Cross-Site Scripting vulnerabilities, each of these payloads will display the page print dialogue.


<img src=0 onerror=print() />

<iframe src="" onload=print()></iframe>

In addition to output being reflected onto the application, it’s common to find that URI values get inserted into pre-existing Javascript code. For a payload to take advantage of this there would need to be limited filtering and any payloads would need to close out the code before exiting.

")}; print(); // 

As we can see from Example #2, the payload closes out the quotation, parenthesis and angle bracket before adding a semi-colon to terminate the line. As the existing code has been completed, the print function can execute which is then followed by a line comment to remove any trailing characters.

Testing For Dom-Based Vulnerabilities

Unlike the previous examples, DOM-based XSS does not reload the web page. This means viewing the page source when testing would not reveal any further information. Since DOM-based vulnerabilities occur when Javascript code adds invalidated code to the page this would mean greater attention would be needed to detect which characters are filtered or sanitized.

Since pages are not reloaded, any injected code commonly makes use of event attributes such as onerror or onload to trigger a given payload. More information on event attributes can be found by heading to the link below.

Evading Application Filters

To protect against Cross-Site Scripting, developers often include features to remove certain characters from any user-supplied data. Although such features can prevent any vulnerabilities from popping up, if implemented poorly then these can be bypassed.

Developers often regular expressions or character matching to detect Cross-Site Scripting payloads. Although this can prove effective against basic payloads it can be bypassed by making some characters uppercase.


Alternatively, HTML or script tags can often get removed from any given input. Sadly, this is very ineffective as tags can be nested. When the full tag is removed it leaves another behind, an example of this can be seen down below.


Another method which can be used to evade application filters is to use character encoding. There are several different methods of encoding which can be used to bypass filters, of these methods is to use HTML entities.

So, what are HTML entities? For some special characters to be displayed on a web page, the HTML entities would need to be used. For example, let’s say we wanted to display an HTML tag as text content. Usually, this would get placed into the application source code and not be visible. To get around this, the HTML entity can be used.

In some situations, HTML entities can be used to bypass any filters but still get included within the application code, an example of HTML entities being used for script tags can be seen below.




For more information on Cross-Site Scripting filter evasion, you can also refer to the OWASP cheat sheet.

Lastly, some Javascript functions which are commonly used in Cross-Site Scripting payloads can often get filtered out. This filtering can either be done by the application or the browser, an example of this is the alert function which commonly gets blocked by Chrome.

Due to the alert function often getting filtered, it could be that a vulnerability exists but the browser is preventing this from working as intended. With this in mind, other such functions such as print or prompt are great alternatives.

Spread the love