One of the most common mistakes in vulnerability assessment is evaluating bugs in isolation. A self-XSS that requires the victim to paste a payload into their own browser gets closed as informational. An open redirect on a login page gets triaged as low severity. A CSRF on a non-sensitive endpoint gets marked as a duplicate. Individually, these are minor issues. Chained together, they can compromise an entire account in seconds.
Our team has spent the last two years focusing on exactly this problem. We look for low-severity vulnerabilities that security teams dismiss, and we find ways to combine them into attack chains that reach critical impact. This post covers our methodology, real-world patterns we have observed, and why bug bounty programs need to rethink how they evaluate seemingly minor findings.
The Chain Mindset
Traditional vulnerability scoring treats each bug as a standalone finding. CVSS assigns a base score, the triage team evaluates exploitability, and the report gets a severity label. This works well for straightforward issues like SQL injection or remote code execution, where a single vulnerability provides direct impact. But it completely fails to capture the risk posed by combinations of lower-severity bugs.
When we approach a target, we do not start by looking for critical vulnerabilities. Instead, we map every behavior that deviates from the expected. Open redirects, reflected parameters, loose CORS policies, missing CSRF tokens on specific endpoints, permissive Content-Security-Policy headers, verbose error messages - all of these go into our notes. The goal is not to find one devastating bug. The goal is to find three or four minor ones that fit together.
Pattern 1: Open Redirect + CSRF + Self-XSS = Account Takeover
This is probably the most common chain pattern we encounter, and it works more often than you would expect. Here is how the pieces fit together.
The open redirect serves as the entry point. The victim clicks what appears to be a legitimate link to the target domain. The URL passes any domain-based validation the victim might perform. The redirect then sends the victim to an attacker-controlled page, which hosts the CSRF payload.
The CSRF exploit targets an endpoint that modifies user-controlled content - a profile bio, a saved search, a draft message. Because this endpoint lacks CSRF protection, the attacker can write arbitrary content into the victim's account. The content includes an XSS payload.
The final link in the chain is the self-XSS. Normally, a self-XSS is worthless because the attacker cannot inject the payload into the victim's browser context. But the CSRF has already done that. When the victim next views their profile, the stored payload executes in their authenticated session. The attacker's JavaScript sends the session token to a collection endpoint, and the account is compromised.
We reported a chain matching this exact pattern to a major platform in late 2019. Each individual bug had been previously reported and closed. The open redirect was a known issue marked as "acceptable risk." The CSRF was closed as low severity. The self-XSS was marked informational. Our chained report was accepted as critical.
Pattern 2: Information Disclosure + IDOR + Privilege Escalation
Another pattern we frequently encounter involves using an information disclosure vulnerability to discover internal identifiers, then using those identifiers to exploit an insecure direct object reference (IDOR) on an administrative endpoint.
In one engagement, we found that a public API endpoint leaked internal user IDs in its response headers. These IDs were not the same as the public-facing usernames and were supposed to be unpredictable. On their own, leaking these IDs was a low-severity issue since there was no obvious way to abuse them.
Separately, we discovered that an administrative settings endpoint accepted user ID parameters without proper authorization checks. Accessing it directly returned a 403, but including a valid internal user ID in the request path returned a 200 with the user's account settings. This IDOR was limited - you could read settings but could not modify them through the same endpoint.
The escalation came from a password reset flow that relied on a security question stored in those same account settings. By reading the security question answer through the IDOR, we could trigger a password reset for any user whose internal ID we obtained from the information disclosure. Three low-severity bugs. One critical chain.
Pattern 3: Race Condition + Business Logic Flaw
Race conditions are often dismissed because they are difficult to exploit reliably. We have found that pairing them with business logic flaws dramatically increases their impact. On one e-commerce platform, a race condition in the coupon redemption endpoint allowed a single-use coupon to be applied multiple times if requests were sent simultaneously. The platform's response was that the financial impact was negligible since coupons were capped at small discounts.
However, the same platform had a referral system that generated single-use coupons automatically. By combining the race condition with the referral system, we could generate an unlimited number of coupons and apply each one multiple times. The financial impact went from negligible to severe.
Methodology for Finding Chains
Our approach follows a few key principles that we have refined through practice.
Document everything. Every anomalous behavior gets recorded, even if it looks useless in isolation. We maintain a running list for each target that includes every redirect, every reflected parameter, every endpoint with missing protections, and every information leak. The list is the raw material for chain discovery.
Map trust boundaries. We diagram where the application transitions between trust levels - authenticated vs. unauthenticated, user vs. admin, read vs. write. Chains almost always cross at least one trust boundary. Knowing where those boundaries exist helps us identify which bugs to connect.
Think in terms of primitives. Each vulnerability provides a primitive - a redirect primitive, a write primitive, an execution primitive, a read primitive. Chains work by connecting primitives in sequence. If you have a write primitive and an execution primitive, you need a delivery mechanism. If you have a read primitive and a write primitive, you have data exfiltration.
Test the full path. A theoretical chain is not a valid finding. We always build a working proof-of-concept that demonstrates the complete attack path from initial click to final impact. This is critical for getting triage teams to accept chained reports.
A Note on Bug Bounty Triage
We want to address something that frustrates researchers across the industry. Too many bug bounty programs close low-severity findings without considering their potential as chain components. When a researcher reports an open redirect and it gets closed as informational, the researcher loses motivation to report the next minor finding. And the program loses visibility into the attack surface that makes chains possible.
Our recommendation to programs is straightforward. Accept low-severity findings at appropriate reward levels. Maintain an internal database of minor issues. When a new minor finding comes in, check it against existing findings for chain potential. The cost of paying small bounties for low-severity bugs is far less than the cost of missing a critical chain.
Our recommendation to researchers is equally direct. Do not report individual low-severity bugs expecting a high payout. Instead, collect them. Find the chain. Report the chain with a full proof-of-concept. Your report will be taken seriously, and you will be compensated for the critical-severity impact rather than the individual bug severities.
Conclusion
The security industry has a blind spot when it comes to vulnerability chaining. Risk assessments that evaluate bugs in isolation systematically underestimate the actual attack surface. Our team's experience shows that most applications with three or more low-severity findings have at least one viable chain that reaches high or critical impact.
We will continue publishing our chain patterns as we encounter them. If you are a researcher working on similar problems, we would like to hear from you. And if you run a bug bounty program, please consider how your triage process handles the building blocks of attack chains.