Introduction
Vulnerability chaining, also known as exploit chaining, is the process of combining multiple vulnerabilities to achieve a more significant or impactful attack. In complex systems, real-world attacks often involve multiple steps, and understanding and mitigating chains is crucial for realistic security assessments.
Before reading this article, it is recommended that you are already familiar with basic web application attacks.
Content
- Introduction
- Content
- CSRF & XSS
- CSRF + XSS
- Stealth Delivery + CSRF/XSS
- File Upload -> XSS
- File Upload -> RCE
- File Upload + File Inclusion -> RCE
- RFI -> RCE
- Open Redirect -> CSRF
- Open Redirect + OAuth Grabbing
- XXE -> SSRF
- XXE -> RCE
- SQL Injection -> RCE
- Clickjacking + DOM XSS
- Host Header Injection + Password Reset
- LFI + Log Poisoning -> RCE
- Conclusion
CSRF & XSS
XSS is a dangerous vulnerability because breaks CSRF protections, making all mitigations for CSRF irrelevant. People sometimes focus only on CSRF mitigations, but don’t let XSS attacks to pass!
XSS attacks can:
- read CSRF token
- send authenticated requests
- runs in same origin
Below I will explain how these 2 can be chained together using CSRF as a delivery method and XSS as execution. CSRF bypasses authentication barrier and converts victim’s privileges into attacker’s injection vector. However, you still need to know the parameters and the format of the requests in order to deliver this.
CSRF + XSS
CSRF is used as delivery method to perform a XSS in the victim browser. This is very impactful because it does not require authentication and could be used in places that requires more privileges.
For example let’s say we have a forum section used just for admins. You do not need access in the website at all to deliver the vulnerability. The CSRF payload is sent to the victim which is admin on the website. Once accessed, it will POST request a comment with the Stored XSS payload that will grab the admins’ sessions for the attacker.
<html> <body> <form action="https://example.com/admin/post/20" method="POST"> <input name="post title" value="<script>malicious</script>"/> <input type="submit"/> </form> <script> history.pushState('', '', '/'); document.forms[0].submit(); </script> </body></html>
Bug bounty reference – https://hackerone.com/reports/1118501
Stealth Delivery + CSRF/XSS
Another similar chaining is to use a stealthier method for your malicious requests. Here, is rather about a cross-site request delivery. The initial malicious URL has the same impact, but different websites can be used as the delivery method.
First case, the attacker wants to hide the malicious URL.
Instead of clicking https://vulnerable.com/abc<script>sent-me-your-cookies</script>, the victim would click an attacker controlled URL that seems normal https://not-malicious.com/. When is accessed, it will trigger the Reflected XSS request to the vulnerable website.
Second case, the attacker uses a vulnerable website visited by the victim as the delivery method. The code is injected in site A and would allow the attacker to redirect the victim to the site B where the attack is performed. In this scenario, the victim does not need to click a malicious link, is just attacked by a legitimate website once visited.
This delivery can be done through HTML injections, malicious Ads, a compromised widget, third-party scripts etc.
Let’s see some examples for this case:
1. Site B is vulnerable to CSRF through a GET request. The malicious code is injected in site A and could be something like this:
<img src="https://victim.com/delete_account">
2. Site B is vulnerable to Reflected XSS.
Let’s say we have https://example-forum.com/, where all employees can talk on different topics (site A).
Then we have https://example-admin.com/, a space just for high privileged accounts (site B).
<meta http-equiv="refresh" content="0;url=https://example-admin.com /issues/2<script>malicious-code</script>">
All users visiting site A will be redirected to the malicious URL that injects JavaScript code in the Admin platform. The initial injection is made in site A for all users, but the attack is targeting the Admin accounts with the access on site B.
File Upload -> XSS
Using an Unrestricted File Upload vulnerability, malicious scripts can be uploaded on the server and used to execute JavaScript code in the victim’s browser. This is helpful when the script becomes too large to be written in one line.
Then, using a HTML Injection, the victims could be redirected to the vulnerable file uploaded that executes JS code in the browser.
Reference – https://hackerone.com/reports/3115705
File Upload -> RCE
Sometimes a File Upload could lead to RCE because an attacker can upload a file that is executable by the web application, such as a web shell or reverse shell. The attacker needs to know the location of the file uploaded and the configuration of the server.
The most common scenario is the application based on PHP server. The attacker uploads a webshell.php and gets RCE if the code is executed. Depending on the environment, the attacker needs to use different payloads, for example:
- .aspx for Microsoft IIS (ASP.net)
- .jsp for Apache Tomcat (Java)
- .js for Node.js
- and others
Is important to check whether the executable is running with the expected extension or not.
File Upload + File Inclusion -> RCE
If the malicious file uploaded is not executed by the browser when the path is visited, a file inclusion vulnerability could be helpful to execute the code from the file.
If the web application allows files to be uploaded as “test.php.png”, in some cases a file inclusion vulnerability could execute the file as PHP.
An example of such file is presented below. When the URL to the file is visited, the web application will try to return it as image.

If the same file is included in the page instead, it could be executed as PHP code.
RFI -> RCE
RFI in most of the cases goes to RCE, because a reverse shell can be hosted on another domain and this can be executed from the target through the RFI payload. What should be tested is if the file is included in the page and if the code is executed.
Open Redirect -> CSRF
Open Redirect can be used to hide the vulnerable URL, making it longer (if is based on GET request). If is based on a POST request, the redirect can be done to an intermediate website controlled by the attacker that is then making the CSRF attack.
- Access
https://vulnerable.com/dashboard?redirect=https://not-malicious.com/ https://not-malicious.com/makes the CSRF attack back tohttps://vulnerable.com/
Open Redirect + OAuth Grabbing
When logging in with OAuth, browser uses a redirect to return the user back to the initial website. Usually just changing the redirect destination with a malicious one will not work, because whitelists prevent attackers from receiving the token.
https://auth.com/authorize?client_id=123&redirect_uri=https://attacker.com/ – should be blocked
However, if an open redirect exists in the victim’s website, then this could be allowed by the whitelist.
https://auth.com/authorize?client_id=123&redirect_uri=https://victim.com/page?redirect=https://attacker.com/
In the end, the attacker is able to obtain the authorization token because this is sent in the URL.
The request sent to the attacker’s website will look like this:
https://attacker.com/#id_token=TOKEN
An example of OAuth Grabbing via Open Redirect + Directory Traversal can be found below on PortSwigger Academy:
https://portswigger.net/web-security/oauth/lab-oauth-stealing-oauth-access-tokens-via-an-open-redirect
XXE -> SSRF
XXE injections could perform SSRF attacks if the malicious XML entity is configured to reference a URL instead of a local file system path. This induces the XML parser on the server to make an HTTP request to an internal or external resource, allowing the attacker to interact with backend systems.
/** Original request: **/]><root> <data>&xxe;</data></root>/** Malicious request: **/]><root> <data>&xxe;</data></root>
XXE -> RCE
Under specific conditions XXE can lead also to RCE. This can happen in different cases, for example:
- if a local file with executable code can be included
- if injection is possible into a file that is then executed by the server
- through vulnerable server components, libraries or extensions
Reference:
https://hackerone.com/reports/500515
https://hackerone.com/reports/227880
SQL Injection -> RCE
If SQL injection is present, sqlmap tool can be used with –os-cmd flag, to execute commands, or –os-shell and –os-pwn to spawn a reverse shell.
In order for this flags to work, the database user must have sufficient privileges to execute commands that interact with the underlying operating system. If all conditions are fulfilled, the sqlmap will provide command execution on the server.
Clickjacking + DOM XSS
Clickjacking can be combined with DOM XSS as the JS code is executed in the iframe of the vulnerable web application. The victim press a button and consequently executes the DOM XSS attack.
Reference – https://portswigger.net/web-security/clickjacking#combining-clickjacking-with-a-dom-xss-attack
Host Header Injection + Password Reset
Host Header Injection is not rated as a high risk, but could become dangerous if is chained with other functionalities. For example if the application uses the Host header value to construct the password reset URL for “Forgot password” functionality. An attacker could manipulate this to redirect victim to a malicious domain, leading to account takeover.
Original link:https://example.com/reset_password?token=22554
Host Header Injection in POST request:
POST /reset_password HTTP/1.1
Host: example.com (change to attacker.com)
email=john.doe@victim.com
The link received on email:https://attacker.com/reset_password?token=22554
If the email parameter is not available, the attack must be performed using Man-In-The-Middle or HTTP Request Smuggling technique.
Reference – https://portswigger.net/web-security/host-header/exploiting/password-reset-poisoning#how-to-construct-a-password-reset-poisoning-attack
LFI + Log Poisoning -> RCE
If a LFI vulnerability exists on a web application and an attacker is also able to inject malicious code into a log file, this could lead to a RCE. For example, using LFI an attacker reads the logs from the server and finds one that stores the User-Agent. A PHP code is injected in User-Agent and stored in the log file. Using LFI the log is included in the page with the PHP code executed.
This example can be seen in the next screenshots:



Conclusion
Chained vulnerabilities in web applications occur when multiple security flaws are combined to escalate the severity and impact of an attack. Individually, these vulnerabilities might have limited impact, but when exploited together, they can lead to significant security breaches. Understanding and identifying these chains is important for security professionals to protect web applications effectively and for developers to implement comprehensive security measures.
Keep in mind that this article only provides a brief introduction to chained attacks, and their successful exploitation depends on many factors.