XSS attacks enable attackers to inject client-side scripts into web pages viewed by other users. The main effects of this vulnerability are the possibility of execution of any actions in the context of the logged-in user, and reading any data in the context of the logged-in user.
Attack scenario
The attacker locates the XSS vulnerability on a website used by the victim, e.g., a bank’s website
The victim is currently logged on to this page
The attacker sends the victim a crafted URL
The victim clicks on the URL
On the victim’s bank website, JavaScriptcode starts executing to intercept the user’s data or execute a transfer on his behalf to the attacker’s account
It is worth noting that operations performed on behalf of the victim may be invisible to the victim, as they may take place in the background using the bank’s API, or the attacker may perform them later with the data needed for authentication, tokens, cookies, etc.
XSS types
1. Reflected XSS
This is one where HTML/JavaScript code contained in any parameter (e.g. GET, POST or cookie) is displayed in response.
A page with a text input to search for something that puts the parameter ?search=foo in the URL ending when querying the API. After entering any phrase, if it is not found, a return message is placed in HTML ex.
<div>No result found for <b>foo</b></div>
We can try to put in the URL ?search=<script>alert('XSS')</script>..
2.DOM XSS
This is when its execution is enabled by the use of dangerous functions in JavaScript, such as `eval` or `innerHtml`. The “Live example” below shows a DOM XSS attack based on the `innerHtml` function.
3. Stored XSS
This is one where the malicious code gets written on the server side. For example, we may send a comment with malicious code to a blog post that is uploaded to the server. Its task is, for example, to wait for the administrator’s moderation and then to steal his session data, etc.
Injection methods
1. In the tag content
`onerror=alert('XSS')`into
<img src onerror=alert('XSS') />
2. In the content of the attribute
`" onmouseover=alert('XSS')` into
<div class="" onmouseover=alert('XSS')"></div>
In the content of the attribute without the quotes
x onclick=alert('XSS')into
<div class=x onclick=alert('XSS')></div>
In the hrefef attribute
javascript:alert('XSS') into
<a href="javascript:alert('XSS')"></a>
In the string inside JavaScript code
";alert('XSS')// into
<script>let username="";alert('XSS')//";</script>
In the attribute with the JavaScript event
');alert('XSS')// where ' is a single quote, into
Using template systems with automatic encoding. Most of the popular frameworks that use such systems protect us from XSS injection (Django, Templates, Vue, React etc.).
Do not use functions like eval or Function with untrusted user data.
Do not use functions and properties that assign HTML code directly to the DOM tree elements, e.g., innerHTML, outerHTML, insertAdjacentHTML, ocument.write. Instead, you can use functions that assign text directly to these elements, such as textContent or innerText.
Be careful when you redirect the user to a URL that is under his control. Risk of injection location = 'javascript('XSS')'.
Filter HTML using libraries such as DOMPurify.
Be careful about uploading .html or .svg files. You can create a separate domain from which the uploaded files will be served.
Use the Content-Security-Policy mechanism.
Take a look at the anti-XSS filters built into most popular browsers.
If you find this article interesting, follow Lukasz on Github: https://github.com/twistezo