There are two main types of XSS that people are referring to when talking about XSS, Persistent (aka Stored) and Reflected. But, did you know there is a third type also, DOM Based?
Furthermore, what's the difference between them and why should I care?
First things first... Cross-Site Scripting (XSS) is a type of computer security vulnerability typically found in web applications. When a site if vulnerable to XSS, it enables attackers to inject client-side scripts into web pages such that it will be viewed by other users or to bypass access controls, such as the same-origin policy, to obtain other users cookies, expose sensitive information, or even take control of another users account.
A good example of reflected XSS is when there is a search that displays the result on the page. Another common reflected XSS you will see is if you notice that the URL is being used by the page as really this can be anything that is being reflected on the page.
In the example below, you can see that the word "me0wz" is reflected in both the search results AND the URL.
In my super basic example below, I was able to get an alert box to pop up. Though this might not seem like much it is an issue because if the malicious user were able to leverage a URL that is being reflected on a page they might be able to input code to create a new account with admin level authorization.
Persistent XSS is where you find an input point that is stored in a database, such as a comment or username, to take advantage of.
If malicious code is able to be saved as part of a username or comment then any time it is viewed on the website, the code will execute.
As you can see with the images below, I am able to input a script tag into the comment form which doesn't appear on the page but instead executes as soon as the page loads.
DOM Based XSS is similar to reflected XSS as it is when some input from the user is stored in a variable in the DOM of the page. This is seen a lot in search results. The tricky part about DOM based XSS is finding where the input point put your input and what it is doing do it.
You can utilize a tool like BurpSuite or Zap to test for these things, but be careful as tools can miss issues if they are not what the tool expects, or you can do what I learned and search over the code itself to see how it is being handled. Personally, I prefer searching over the code myself because it allows me to see each step that the DOM is making to handle the input and where it ends up.
In the image above you can see that the search is placing the search-term into an image tag. This is an odd thing that can be leveraged by breakinging out of the image tag and adding in malicious code into the image tag in the DOM.
The best way to help prevent XSS is to not trust input. This seems like an obvious thing, but depending on if/how the input is sanitized or encoded will determine how secure the site is from XSS.
However, be careful with filtering systems as it might be possible to leverage them to inject code. If the filter is looking for specific tags and you can use their special tags to make code execute, the malicious user wins.
It should be noted that sanitizing/encoding/filtering/validating input should be done not only on the client-side but also on the server side. Client-side will make for a better user experience as users won't have to wait for the server to respond before getting an input error and server-side will protect the server from malicious code.
Here are a few more things you can do from PortSwigger...
" - Filter input on arrival. At the point where user input is received, filter as strictly as possible based on what is expected or valid input.
- Content Security Policy. As a last line of defense, you can use Content Security Policy (CSP) to reduce the severity of any XSS vulnerabilities that still occur." (3)