XSS is one of the most popular vulnerabilities, if not the most. While XSS has dropped from the 2nd place in the OWASP 2010 top 10 to the 7th place in the OWASP 2017 top 10, it is still very common and loved by the researchers.

What is XSS?

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.



XSS has can be split up in different categories. The severity often differs in the way the victim interacts with the vulnerable web page.

An attacker can use XSS to inject some malicious script into the vulnerable application. The attacker-supplied code can perform a wide variety of actions, such as stealing the victim’s session token [when HTTPOnly is flagged false] or login credentials by making a fake login form, performing arbitrary actions on the victim’s behalf, and logging their keystrokes. If the victim has special privileges within the application, or has access to sensitive data, this can cause a serious vulnerability.

Reflected XSS

Reflected XSS occurs when user input from the request is reflected in the webpage without safely escaping. A basic example would be the search functionality. The search query is often reflected in the webpage.

A well-written blogpost on how Jonathan Boumann found a Reflected XSS by going a step further then most would.

How I XSS’ed Uber and Bypassed CSP by Efkan.

Reflected XSS on admin.google.com by Brett Buerhaus.

From Reflected XSS to Account Takeover by A Bug’z Life

Stored XSS

Stored XSS occurs when user input is saved in a data store and shown in an unsafe way on the webpage. A basic example would be a blog post where it is possible to leave a malicious comment. Each time a victim visits the page, the XSS triggers. The impact of stored XSS is higher then reflected XSS because the victims doesn’t need to be convinced to visit a certain page and can trigger the XSS by just browsing on the site.

A creative way to gain Stored XSS requiring a specific scenario by OMESPINO.

A blog post by Jonathan Boumann showing that XSS can be more then just an alert box.


DOM XSS occurs when user input is processed by javascript in an unsafe way and reflected on the page. A basic example would be javascript code that uses user input in the document.write() function.

Finding DOM XSS in obfuscated javascript by Daniel Maksimovic.

XSS via PostMessage

The pitfalls of postMessage by Mathias Karlsson from Detectify.

A blog post explaining “The Mystery of postMessage” by Ron Chan.

Blind XSS

Blind XSS occurs when user input is stored in a data store and shown in an unsafe way on the webpage. The difference with stored XSS is, that it’s hard to confirm the vulnerability since the attacker doesn’t have access to the page where the payload might trigger (hence the word “Blind”). Blind XSS often trigger in admin panels. A basic example would be the contact page, where you are able to send a message to employees/admin of the company, your message or other details (like your user-agent) might be reflected in an unsafe way on the employee his page. A great tool to help you test for blind XSS is XSSHunter.

A blog post about Blind XSS for beginners by Syntax Error.

Blind XSS in the X-Forwarded-For HTTP header in a WordPress plugin.


Self-XSS occurs when your own user input gets reflected in an unsafe way. (whether it is stored or just reflected XSS). The problem is that you can exploit the XSS only on yourself (hence the word self) or you have to convince the victim to past javascript code in the browser (which is rather unlikely). Most programs don’t accept self-XSS so it is better to use the vulnerability to chain it with CSRF for example.

Chaining CSRF and Self-XSS to stored XSS by Renwa.

Chaining multiple vulnerabilities to exploit Self-XSS by Geekboy.


XSS via Flash

While Adobe Flash is old technology that is dying, it might be possible to still encounter flash files with a XSS vulnerability.

A comprehensive blog post about “Analysing SWF files for vulnerabilities” by MLT.

A write-up about XSS in Mega.co.nz by Frans Rosén from Detectify.


Time for practice!

A while ago we made our own XSS CTF challenge. Check it out!
The XSS challenge that +100k people saw but only 90 solved.

The unescape room, an XSS challenge by Jobert Abma. Try to beat the 10 levels!

An XSS game by Google. Try to beat all the levels. There will be cake at the end of the test. 

BugBountyNotes has several XSS challenges with different levels of difficulty available!

How to prevent XSS?

A short summary of the XSS prevention cheat sheet by OWASP:

  1. Never Insert Untrusted Data Except in Allowed Locations
  2. HTML Escape Before Inserting Untrusted Data into HTML Element Content
  3. Attribute Escape Before Inserting Untrusted Data into HTML Common Attributes
  4. JavaScript Escape Before Inserting Untrusted Data into JavaScript Data Values
  5. CSS Escape And Strictly Validate Before Inserting Untrusted Data into HTML Style Property Values
  6. URL Escape Before Inserting Untrusted Data into HTML URL Parameter Values
  7. Sanitize HTML Markup with a Library Designed for the Job
  8. Avoid JavaScript URL’s

How to prevent DOM XSS specifically? There is a separate prevention cheat sheet for DOM XSS by OWASP.

For our .NET developers, a post about XSS in .NET by Troy Hunt.

Want more?

Check out LiveOverflow his channel, he has some really good video’s about XSS.

Great video showing XSS can be more then inserting alert(“1”) everywhere.


Simple explanation about XSS by Computerphile

Also follow us on twitter for more #BugBountyTip and don’t forget to subscribe to our weekly Bug Bytes, a newsletter curated by Pentester Land & powered by intigriti containing more write-ups and helpful resources.