CSRF Chained with Logic Flaws
detect, understand, remediate
A chained CSRF finding is one in which the forged request alone is not the impact, the impact is the downstream logic flaw the forged request reaches: an IDOR that crosses a tenant boundary, a race condition that opens a state window, a mass-assignment that flips a privileged property, a state-machine skip that bypasses a checkout step, or a content-type confusion that defeats the framework defence. The chain is the finding, not just the missing token.
No credit card required. Free plan available forever.
What is a CSRF chain finding?
A chained CSRF finding is one in which the missing anti-CSRF defence is only the entry symptom; the impact lives in the downstream logic flaw the forged request actually reaches. The classic cross-site request forgery page covers the wire-side defence: anti-CSRF tokens, SameSite cookies, Origin and Referer validation. A chain finding starts at that same wire-side gap and ends inside an insecure direct object reference, a race condition, a mass assignment, a state-machine skip, or a content-type confusion that turns the missing token from a medium-severity hygiene finding into a high-severity exploitation path. The CWE chain is CWE-352 paired with one or more of CWE-639, CWE-362, CWE-915, CWE-840, and CWE-200.
The shortest way to recognise a chain finding: the forged request is not the bug, it is the carrier. A standalone CSRF on a low-impact endpoint (toggling a preference, dismissing a notification) deserves a moderate severity and a token-and-SameSite remediation. A chain finding on a high-impact endpoint behind the same missing defence deserves CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N or higher because the forged request crosses a trust boundary, leaves the authority of the victim user, and lands in a downstream handler that itself fails to enforce authorisation, idempotency, or input validation. The fix lives in both layers: restore the wire-side defence and remediate the downstream logic flaw the chain exploited.
Chain findings are the most under-reported CSRF class in pentest reports and the most under-scored CSRF class in scanner output. Pentest reports often record the missing token in isolation and miss the IDOR or mass-assignment one parameter deeper. Scanners often surface a SameSite=None cookie or a missing token endpoint without ever following the chain into the authorisation layer. The right place to catch the chain is the engagement record itself, where the missing-token symptom and the downstream finding are paired through the same evidence trail and routed to the same remediation owner. SecPortal handles that pairing through findings management with CVSS 3.1 scoring, authenticated scanning that walks logged-in workflows, code scanning against connected repositories, and retesting workflows that pair the chain re-verification to the same finding record.
How a CSRF chain forms
Every chain finding follows the same four-step shape: the wire-side defence is missing or bypassable, the attacker reaches a state-changing handler under the victim's authority, the handler trusts a client-supplied value the design never authorised, and the resulting state change crosses an authorisation, idempotency, or workflow boundary the application was relying on. The four steps look like this.
Wire defence is missing or bypassable
No anti-CSRF token; or a token that is not validated; or SameSite=None cookies; or SameSite=Lax with top-level navigation reaching a GET state-changing endpoint; or a JSON endpoint that accepts text/plain or missing Content-Type and so skips preflight.
Forged request reaches a handler under victim authority
The browser attaches the session cookie. The handler sees an authenticated request from the victim. The wire-side identity check passes. The handler is now executing with the victim's privileges and trust.
Handler trusts a client-supplied value the design never authorised
The forged request supplies a target object identifier the victim has no business touching (IDOR), a role or permission flag the design did not allowlist (mass assignment), a sequence position the workflow never reached (state skip), or a timing the design never modelled (race window).
State change crosses an authorisation or workflow boundary
The result is the chained impact: another tenant's record is modified, a privileged property is flipped, a checkout step is skipped, a refund window is forced, or a state machine is left in a state the design did not anticipate. The forged request is now exfiltration, escalation, or financial impact.
Seven chain patterns to test for
A chain finding only exists if the downstream handler also fails. Test for these seven combinations as a checklist on any application that holds tenant-scoped data, financial state, or workflow state. Each pattern names a wire-side weakness on the left and a logic weakness on the right that produce the chained impact when paired.
Missing token plus IDOR
Forged POST to /account/{id}/email reaches the handler under the victim's session, the handler trusts the supplied {id} without an authorisation check, and the email of another tenant's account is rewritten. The CWE chain is CWE-352 plus CWE-639.
Missing token plus mass assignment
Forged form submission carries role=admin alongside the expected name and timezone fields. The handler deserialises the form into the user model without a property allowlist. The victim's role flips. The CWE chain is CWE-352 plus CWE-915.
Missing token plus state-machine skip
Forged POST hits /checkout/complete without /checkout/payment having ever fired. The handler does not verify the prior state and marks the order complete. The CWE chain is CWE-352 plus CWE-840.
GET state change plus SameSite=Lax exemption
A GET endpoint mutates state (delete, transfer, confirm). SameSite=Lax exempts top-level navigation, so an attacker page can window.location to the GET URL and the browser still attaches the cookie. The CWE chain is CWE-352 plus CWE-840.
Missing token plus race condition
Forged request lands in a TOCTOU window the design never modelled. Two concurrent forged requests pass a single check-then-act gate, the balance goes negative, the refund double-credits, or the gift card redeems twice. The CWE chain is CWE-352 plus CWE-362.
JSON content-type confusion plus business logic
JSON endpoint accepts text/plain or missing Content-Type so preflight is skipped. The endpoint handles a financial transition without idempotency. The forged text/plain submission is processed as JSON and the transition fires. The CWE chain is CWE-352 plus CWE-840.
Missing token plus role elevation
Forged POST to /team/{userId}/role carries role=admin under a low-privilege victim's session. The handler reads the {userId} and the {role} from the body without verifying the actor has authority to grant admin. The CWE chain is CWE-352 plus CWE-269.
Missing token plus open redirect bait
A separate open-redirect endpoint is used to land the victim on an attacker page that triggers the chain. The redirect is not the impact, it is the bait. The CWE chain is CWE-352 plus CWE-601 in the kill chain, with the downstream chain still in CWE-639, CWE-915, or CWE-840.
How to detect a chain
A chain finding requires two passes through the same request: the wire-side pass that confirms the defence is missing or bypassable, and the downstream pass that exercises the logic flaw the chain reaches. Single-pass detection records the symptom and loses the chain. The detection discipline below is what an authenticated scanner, a code scanner, and a manual test together have to surface for the chain to land on the engagement record as a chain finding, not as two unrelated findings or as a single under-scored CSRF entry.
Automated and tooling signals
- SecPortal authenticated scanning walks the logged-in workflow, identifies state-changing endpoints, then replays each one without anti-CSRF token, with SameSite=Lax exempt top-level navigation, with stripped Origin header, and with text/plain Content-Type. Each missing-token result is then paired with downstream IDOR, mass-assignment, role-flip, and state-machine-skip checks on the same endpoint so the chain shows up as a chain finding.
- Cross-role replay runs the same request that the wire-side check confirmed reaches the handler under a second tenant identity and a non-privileged role, surfacing the IDOR chain and the role-elevation chain that turn a CSRF symptom into a chain finding.
- External scanning enumerates Set-Cookie headers across the verified perimeter for SameSite attribute, Secure attribute, HttpOnly attribute, scoped prefix, and SameParty so the workflow-side chain finding records the wire-side configuration in the same engagement evidence.
- Code scanning runs Semgrep rule packs against the connected GitHub, GitLab, or Bitbucket repository for state-changing route handlers without CSRF middleware, GET handlers that mutate state, JSON deserialisers that accept text/plain or missing Content-Type, mass-assignment binders without an allowlist, and IDOR-prone repository queries that key off a client-supplied identifier without a server-side authorisation check.
- Findings management lets the chain finding carry both CWE entries in the finding header (CWE-352 plus the downstream CWE), a CVSS 3.1 vector that reflects the chained impact rather than the missing-token symptom alone, and the engagement-level evidence chain from the scanner output, the manual reproduction, and the code-scanner rule hit.
Manual test plan
- Enumerate every state-changing endpoint in the authenticated surface. For each endpoint, attempt the request from a second-origin HTML page with the victim's session active and record whether the request reaches the handler.
- For each handler the forged request reaches, walk the parameter set and try the chain combinations: replace the object identifier with a second tenant's identifier (IDOR), add a privileged property name to the body (mass assignment), change the state machine position (skip), introduce concurrency through two parallel requests (race), and swap Content-Type to text/plain (preflight skip).
- Test SameSite=Lax exempt navigation by hosting a link that triggers a top-level navigation to a GET endpoint that mutates state. Confirm whether the browser still attaches the cookie and whether the handler still executes the mutation.
- Record the chain on the finding with CWE-352 plus the downstream CWE, the wire-side missing defence as the entry symptom, the handler trace as the chain body, and the downstream business impact as the chain outcome. Calibrate severity to the chained impact, not the missing token alone.
How to fix a chain
A chain finding has two fixes, both required. Fixing only the wire-side defence leaves the downstream logic flaw open to other entry paths (a compromised first-party page, a server-side request, a misconfigured CORS allowlist). Fixing only the downstream logic flaw leaves the wire-side gap available to the next chain that finds a different downstream weakness. The pair below is the minimum surface a chain finding has to close before retest.
Restore the wire-side defence on every state-changing endpoint
Add anti-CSRF tokens or use the framework primitive (Next.js Server Actions origin check, Django CsrfViewMiddleware, Rails authenticity token, Spring CsrfFilter) on every state-changing route. Set session cookies to SameSite=Strict or Lax depending on the redirect surface. Validate Origin or Referer on every mutating request. Treat GET handlers that mutate state as a defect and convert them to POST or DELETE.
Close the downstream logic flaw on the same endpoint
Pair the wire-side fix with the chain-specific fix. For an IDOR chain, add a server-side authorisation check that verifies the actor owns the target identifier (no client-supplied identifier trusted without verification). For a mass-assignment chain, allowlist the deserialisable property set on the binder. For a state-machine chain, model the workflow as an explicit state machine and verify prior state before each transition. For a race chain, add idempotency keys, optimistic locking, or a single-row select-for-update on the critical section. For a content-type confusion chain, reject non-JSON Content-Type on JSON endpoints and enforce CORS preflight by design.
Reject GET for state-changing actions
A GET endpoint that mutates state is exploitable through SameSite=Lax top-level navigation and through image and iframe loads. Convert every state-changing GET to POST, PUT, PATCH, or DELETE and add the same anti-CSRF and Origin discipline to the new method.
Re-authenticate on high-impact transitions
For password change, email change, payment surface change, role assignment, MFA enrolment, and account deletion, require the user to re-enter credentials or pass a second factor before the transition. The re-authentication is a CSRF-resistant gate because the attacker cannot supply the user's password or second factor through the forged request.
Add audit logging that captures the chain
Log every state-changing request with the actor identity, the target identifier, the prior and posterior state, and the originating Origin or Referer header. The log entry is both the audit evidence and the chain re-verification artefact. Send chain-relevant events to the activity log so the security team can pivot from a chain finding into the production trail.
How SecPortal records and tracks a CSRF chain
SecPortal does not replace the manual reasoning that links a missing token to a downstream IDOR. It is the workspace where the wire-side scanner output, the cross-role replay, the code-scanner rule hit, and the manual reproduction land on one finding record so the chain stays paired through severity, ownership, evidence, fix, retest, and audit. The flow for a chain finding looks like this.
Record the chain with both CWE entries
Capture the chain on a finding with CWE-352 plus the downstream CWE in the finding header (CWE-639 for IDOR, CWE-915 for mass-assignment, CWE-362 for race, CWE-840 for state-machine, CWE-269 for role flip). The CVSS 3.1 vector reflects the chained impact, not the missing token alone.
Attach the chain evidence in one place
Upload the second-origin HTML proof, the captured request and response pair, the scanner output excerpt, the code-scanner rule hit, and the reproduction notes through document management so the chain audit trail lives on the finding rather than in scattered shares.
Route to a single remediation owner
A chain finding has two fixes but one owner. Assign the chain to the engineering owner of the affected route. The route owner pairs the wire-side fix and the downstream logic fix in one change set so retest can verify both halves together.
Pair the scanner output with the manual chain
Use authenticated scanning for the wire-side missing-token sweep and code scanning for the static-rule sweep against the connected repository. Pair the automated outputs with the manual chain reproduction on the same finding through the engagement record so the chain has both the scanner footprint and the manual exploitation trace.
Track the chain through the standard SLA
Apply the standard severity-based remediation SLA based on the chained CVSS 3.1 vector, not the wire-side symptom score. A chain finding with confidentiality and integrity impact on a critical asset earns the critical SLA window.
Retest both halves through the same record
Pair the retest to the same chain finding through retesting workflows. The retest verifies the wire-side defence is in place (token required, SameSite set, Origin validated) and the downstream logic flaw is closed (authorisation check on the identifier, allowlist on the binder, state machine verifies prior state, idempotency key on the race section).
Use the exception register for accepted-risk chains
Where remediation is delayed by a legitimate constraint (legacy framework, vendor surface, planned retirement), record the chain as an accepted-risk exception with a named approver, a stated rationale, an expiry date, and a compensating control through finding overrides.
Surface the chain in the compliance trail
Compliance tracking pairs the chain finding to the relevant OWASP, ISO 27001, SOC 2, PCI DSS, and NIST control rows so the audit evidence for chain remediation reads cleanly during fieldwork. The chain is also visible in the activity log for the chronology of detection, decision, and fix.
Read the chain through global search
Search for the affected asset, the chained CWE pair, or the responsible owner across the workspace to surface the chain finding from any starting point. The chain finding is reachable from every adjacent investigation, not only from the engagement it was raised on.
Related vulnerabilities and recommended reading
A chain finding sits at the intersection of cross-site request forgery and a downstream logic class. The pages below cover the wire-side baseline, the downstream classes that most commonly form the chain, the design-stage category that captures the root cause, and the SecPortal workflows that hold the finding record across the chain's two-fix discipline.
- Cross-site request forgery (CSRF) the wire-side baseline that covers anti-CSRF tokens, SameSite cookies, and Origin or Referer validation, and the entry symptom of every chain finding.
- Insecure direct object reference (IDOR) the downstream class that turns a missing-token symptom into a cross-tenant rewrite of another account's data.
- Mass assignment the deserialisation pattern that lets a forged form set role, permission, tenant, or owner fields the binder never allowlisted.
- Race condition the timing class that lets two parallel forged requests slip through a single check-then-act gate the design never modelled.
- Business logic flaws the broader logic category that hosts the state-machine skip, the idempotency gap, and the workflow assumption a forged request can exploit when the wire-side defence is missing.
- Insecure design (A04:2021) the upstream design-stage category that explains why the chain exists: the threat model never enumerated the abuse case that the wire-side gap plus the logic flaw together compose.
- Broken access control the OWASP A01 parent category that the IDOR and role-flip chain endings fall under.
- Insecure cookie attributes the attribute-set discipline that covers SameSite, Secure, HttpOnly, and scoped prefix, and the configuration row a chain finding records alongside the missing token.
- Parameter tampering the request-modification pattern that names the chain's middle step when the attacker rewrites an identifier or a property the design never authorised.
- Broken object level authorization (BOLA) the OWASP API Top 10 framing of the IDOR chain when the affected endpoint is an API rather than a browser-form endpoint.
- OWASP Top 10 the catalogue under which the chain's wire-side and downstream halves are categorised (A01 Broken Access Control, A04 Insecure Design, A05 Security Misconfiguration).
- OWASP ASVS the verification standard that lists CSRF defence and authorisation enforcement at Level 1, 2, and 3, and the checklist a chain finding maps onto for design-stage rework.
- API security testing checklist the operational checklist that names the chain combinations for API endpoints where the JSON content-type discipline and the per-tenant authorisation check are the most common chain participants.
- OWASP Top 10 explained the parent reading for the A01 and A04 categories a chain finding maps under.
- Web application testing the engagement shape that hosts the workflow-side chain reproduction alongside the wire-side scanner sweep.
- API security testing the engagement shape for the API-side chain where JSON content-type, BOLA, and IDOR are the most common downstream classes.
- Security finding fix verification the retest workflow that pairs the two-halves remediation to the same finding record and confirms both the wire-side defence and the downstream logic fix landed.
- SecPortal for AppSec teams the audience overview for the teams that own chain triage across the authenticated application surface.
- SecPortal for product security teams the audience overview for the product security organisations that pair the wire-side fix with the design-stage rework a chain finding implies.
Compliance impact
OWASP Top 10
A01:2021 Broken Access Control, A04:2021 Insecure Design
OWASP ASVS
V4 Access Control, V13 API and Web Service
ISO 27001
A.8.28 Secure Coding, A.8.25 Secure Development Life Cycle
PCI DSS
Req. 6.2 Secure Development
SOC 2
CC8.1 Change Management
NIST 800-53
SA-11 Developer Testing and Evaluation, AC-3 Access Enforcement
NIST CSF 2.0
PR.PS Platform Security, PR.AA Identity Management
CIS Controls
Control 16 Application Software Security
Related features
Test web apps behind the login
Vulnerability scanning tools that map your attack surface
Find vulnerabilities before they ship
Vulnerability management software that tracks every finding
Verify fixes and track reopens on the same finding record
Finding overrides that survive every scan cycle
Compliance tracking without a full GRC platform
Every action recorded across the workspace
Repository connections for SAST and SCA
Document management for every security engagement
Orchestrate every security engagement from start to finish
Track CSRF chain findings on one engagement record
SecPortal records the missing-token symptom and the downstream IDOR, race, mass-assignment, role flip, or state-machine skip on one finding chain, with CVSS 3.1 severity, CWE-352 and the chained CWE in a single finding header, retest pairing, and an append-only activity log. Start scanning for free.
No credit card required. Free plan available forever.