Generally referred to by its
English nomenclature, Cross-Site Scripting, this type of
vulnerabilities in applications are often underestimated by the
development teams of companies, because they have traditionally been associated
to purely browser attacks that affect the client, without going beyond
'some link as a phishing attempt, etc. But the reality is that this type
of attacks, especially combined with the exploitation of others
existing vulnerabilities can cause significant harm.
They consist mainly of the
malicious code injection (usually JavaScript, although also vbscript
in specific cases), in the content of applications or web pages that others
users can see. Through this code, data can be stolen.
sensitive information, such as cookies or credentials, redirect the user to sites
malicious, or impersonate the affected user, to carry out
actions on your behalf without your consent.
There are several types of XSS,
highlighting fundamentally three major classifications, which will be detailed in
continuation.
To do this, and before starting, one
will use an application with certain vulnerabilities enabled (in this
case those related to XSS), for learning. The application consists of a
basic login form, where access is granted either with a user role or with
administration to a panel, from where some items are managed with their
price and in case of being the administrator, the management of users of the
application, as well as other aspects.
Types
Reflected XSS
It basically occurs when the user's input is processed and reflected directly on the web page, without being properly validated or encoded. This would allow for code injection in such a way that when that request is executed, the result of that injection is reflected. In this way, the URL could be sent (perhaps hidden under a URL shortener, which would be sent to the user, the target of the attack). Thus, when the user executes that link, they would also execute the JavaScript code contained in the URL, which could be a redirection to the attacker's website where, for example, the user's session cookie on the current website would be stolen. Another example would be the execution of a malicious "hook" against the victim's web browser, controlled from that moment on by the attacker (using the Beef application, a well-known framework for web exploitation, for example).
Thus, returning to the mentioned vulnerable application, if you check in the section of the list of items, the search field that allows the user to search for certain items:
- "Connecting to the application as user1, you can access that user's items in the item list through the "Manage Your Items" menu."
- If you search for an item (name or description) that exists, for example "item 1":
As can be seen, the result is reflected in the response.
- Now it will be tested to search
for a script to see if the browser interprets as code or
not the answer:
-
Injecting HTML code (for example, the typical header between
...
):
Indicates that, at least, it is interpreting the HTML code without any filter, allowing HTML code to be injected, which is interpreted by the browser.
- Injecting JavaScript code. It will not be achieved with typical messages. , but there are many payloads, with a good reference on the PortSwigger Academy page. Or if not, trying different URL encodings. One of the possible payloads, for example, would be to inject an HTML object of type image whose loading error triggers the execution of a script (and there, to test, the typical alert):
A
B
- 'Intercepting the request with BurpSuite, the response that the search actually receives is analyzed, which will load the result via Ajax through the search parameter in' items_search.php:
By resending the response to the browser, the vulnerability can be checked:

-
The next step would be, for example, to set up a small web service on the attacking machine in such a way that the payload is slightly modified (for example, by to steal the user's cookie who will forward that request. For example, if the URL with the payload is sent in the encoded search parameter and entered into a URL shortener to the site administrator.
Stored XSS
This is one of the most critical vulnerabilities within the different types of XSS, as it is the only case where the injection can be persistent, since the malicious code is permanently stored on the server, and affects all users who view the content, not just those who click on the malicious link. In other words, there is an interaction with the server, which could be combined with other vulnerabilities to even gain control over access to it. It is the typical case regarding opinion comment forms on a site, etc. Although it could also occur in other types of data, such as tables that store results previously entered by the user, where the fields have not been properly validated.
Returning to the previous example of the vulnerable application. In the management of items, it can be seen that there is a button for creating new items (Add New Item). If code can be injected into any of the fields of the new item (either through each field, or by intercepting the request with a web proxy) taking into account the URL encoding of spaces and other special characters), this XSS will be stored for all users of the application.
- Having logged in with another user (user2), the goal now is to insert a specific XSS to test if the page is vulnerable at this point. For example, in the same example as before, it allows creating new articles. If a payload of the type is inserted in the description field (which is long enough to insert the necessary characters). When saving the article:

- 'Once it has been verified that it is vulnerable, the article is removed (or edited, and the description is replaced) and another one is created that does not directly display the result on the screen, but instead sends, for example, the user's cookie to a web server running on the attacker's machine, with the following payload:'
When executing the modification/registration, nothing apparently strange will be observed in the resulting table:
However, on the web server running on the attacking machine:
- When the administrator user, who has access to all articles, opens that page:
and the script executed by the attacker will be silently launched, the administrator's cookie will be displayed as part of the parameter of the request made to the attacker's web server:

The difference (and the criticality) regarding reflected XSS is notable: any user who has access to that record will be affected, whereas, in the reflected case, it would require sending the malicious link to each of the target users of that attack.
- Similarly, this script could be replaced by a hook.js from Beef to control the browsers of users connecting to this page, or to execute more sophisticated scripts that could jeopardize other information on the web server.
DOM-based XSS
In DOM-based XSS (Document Object Model), the malicious code is executed directly on the client side, manipulating the browser's DOM without interacting with the server. Thus, what is done is a manipulation or modification of the dynamic content of the page, by executing JavaScript code on the client, in those parameters or fields of the page that have not been properly encoded or validated. Therefore, all users who execute the manipulated page will be affected by this type of attack.
In the example application, when a user successfully logs in to the website, a welcome message is shown as a transition, which is directly injecting and without validation, the name of the logged-in user, into an .innerHTML of the HTML object intended to contain the welcome message.

You can manipulate that .innerHTML by injecting the corresponding script, in such a way that the DOM of the response is modified at runtime, in the client's browser:
'And the administrator's session cookie is stolen, as can be seen on the attacker's server:'
As the welcome message redirects to the admin panel, after two seconds, the administrator will not have been aware that their session cookie has been stolen.
Combined attacks: CSRF token evasion exploiting XSS vulnerability
In the example application, there is an administration panel (users_mgmt.php), managed only by the site administrator (user admin):
The Observations field is vulnerable to XSS. Each user can modify their profile once logged in on their corresponding profile change page, user_edit.php (including the password).
If you observe the detail of the code, the webpage contains a token that prevents possible CSRF/XSRF (Cross-Site Request Forgery) attacks.
"If a study of the strength and randomness of these tokens is conducted using the BurpSuite sequencer, one can conclude that it is a token robust and reliable enough to not be easily guessed, far from being susceptible to brute force attacks."
In 2260 analyzed tokens, none of them were repeated even once.

However, as mentioned earlier, it is known that the observation field is vulnerable to XSS. In the event that this occurs, the strength or randomness of the token used does not matter: the page will be vulnerable to CSRF, even if it has been protected.
Thus, this injection could be abused in the observation field, to create a script that reads the (anti) CSRF token from the current page and helps to evade it, for example by executing a password change for the administrator user (note that the record identifier is given by an id, and this id is used in user management, to edit each user, including the administrator themselves (presumably the identifier 1 of the table, since the "hacker" user has the identifier 6).
Thus, the user "hacker" after intercepting with Burp and studying the modification requests of each of the fields and the results, could create, for example, the following script, to dynamically capture the current token from the DOM, and with it modify the password of the user "admin", stealing the account:

Thus, inserting the script in the Observations field:
it would be achieved that when the user "administrator" enters the user management, it unknowingly activates the script, which will automatically change the password, allowing the user "hacker" to steal their account:
At this moment, the user "hacker" will be able to log in with the administrator account and the new password...

Conclusion
One should never underestimate the power of XSS injections, as they can lead to serious problems, including the complete takeover of the web server, if combined well with other existing vulnerabilities on the site.
Prevention measures
For proper mitigation of XSS, a series of best practices should be applied in the development of web applications:
Server-side and client-side validation
"It is not enough to apply validations on the fields or user input parameters on the client side, because these controls could be bypassed (simply by avoiding client-side validations by omitting the corresponding scripts). It is necessary to have proper validation on the server side, validating the data entered (or intercepted and manipulated through a web proxy), and discarding those that may be dangerous or do not fit the specific functionality of the application."
Correct application of functions for escaping and encoding
It must be ensured that the encoding of the data entered by the user is correct before the data is interpreted by the browser, escaping characters considered "dangerous" using the functionality available in the server-side language used for this purpose. For example, in PHP there are functionalities like htmlspecialchars or htmlentities that escape certain characters (or all possible ones, in the case of the latter) to their HTML equivalent. These measures alone are not 100% reliable, as there are evasion techniques, but when combined with others and good validation, they are a good defensive option.
Use of "whitelists"
Use of whitelists versus the use of lists that exclude certain registered characters or expressions. It is always better to authorize the use of certain information than to reject the use of others, for which a system of evasion or substitution could always be sought. This should always be taken into account when establishing certain rules in the WAF (Web Application Firewall) employed.
Use of methods to avoid dynamic construction of the DOM (Document Object Model)
"Safe methods should always be attempted to avoid the insertion of unvalidated data into the DOM, through JavaScript, such as setAttribute or textContent, instead of innerHTML, for example."
Use of security headers
Content Security Policy (CSP)
Implement, with this security header, a content security policy to restrict what types of resources can be executed in the web application, preventing or blocking the injection of malicious scripts.
Content-Security-Policy: default-src 'self'; script-src 'self' http://example.com; object-src 'none'
>The previous code will allow loading resources only from the same origin as the server, permitting only the loading of scripts from the same origin or the fictitious site https://example.com, completely blocking the loading of objects such as embed, object, or applet, which could be potential attack vectors.
X-Content-Type-Options
Avoid attacks based on content analysis (MIME sniffing) in order to attempt to execute malicious scripts:
X-Content-Type-Options: no-sniff
X-XSS-Protection
Activate the XSS filter used by some browsers to prevent the execution of certain malicious scripts through this header. Not as robust in terms of security as the previous headers, but a useful additional measure: The filter is enabled, and if an XSS attack is detected, the browser blocks the execution of the script, instead of trying to sanitize the content (in any case, server-side sanitization measures should always be implemented).
X-XSS-Protection: 1; mode=block
X-Frame-Options
"By the explicit prohibition of embedding this page within any X-Frame, it is ensured that clickjacking attacks that could be combined with XSS cannot occur, incorporating an attacking page that executes the injected malicious script within an iframe."
X-Frame-Options: DENY
Cross-Origin Resource Sharing (CORS)
Through the CORS header, it is controlled which domains can make requests to the web server from other origins. When configured correctly, it can limit access to sensitive resources from malicious sites (including combinations of XSS with SSRF, etc.).
Access-Control-Allow-Origin: http://example.com
Cache-Control
If a poor cache storage configuration is used, it could lead to the insecure storage of malicious or sensitive content. In this way, by properly configuring this header, it will be possible to prevent certain dynamic content that is executed in response to specific forms from being cached.
Cache-Control: no-store, no-cache, must-revalidate
Referrer-Policy
Although this header is not directly related to XSS, if the browser were to send certain information as part of the Referrer header, an attacker could take advantage of this information to exploit certain sensitive data from the URLs displayed as part of this header, which sometimes include injectable parameters, to exploit an XSS, for example.