# State-changing routes missing sibling-path checks

Setup, alternate-submit, or GET-mutation routes that skip auth, CSRF, 2FA, or policy enforced elsewhere

_Area: Web business logic and race conditions. Seen in 8 disclosed reports; 3 confirmed bounties, median $3,370, range $750-$10,000; latest 2024-01-31. Updated 2026-10-23._

## How it works
A privileged action (finish setup, transfer a domain, submit a report, delete a file) is reachable through a route that does not run the checks its sibling routes run. The broken assumption is "the guard on the main path covers every path" or "this endpoint is only hit by trusted callers." Either the route has no auth/CSRF at all, its guard is written so a caller can satisfy it trivially (a check that only fires when a parameter is empty), a second entry point reimplements the action without the shared authorization, or a state-changing action is exposed as a GET so no token is ever expected.

## Where it shows up
- Setup/install handlers whose guard only redirects when a parameter is empty; supplying any Action skips the completed-setup check [E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-logic-flaw-leading-to-rce-in-dynamicweb-9-5-0-9-12-7.md).
- State-changing actions performed via GET (GraphQL mutations over query string, transfer links) where CSRF tokens are only enforced on POST [E1](https://bugbountylibrary.com/r/h1%3A1122408.md)[E4](https://bugbountylibrary.com/r/h1%3A416978.md).
- Dev/debug mounts (mail viewers, admin panels) on localhost with destroy/delete routes lacking CSRF and auth [E5](https://bugbountylibrary.com/r/h1%3A1353103.md).
- User-controlled ids passed into filesystem sinks (rm_rf) with `../` traversal [E5](https://bugbountylibrary.com/r/h1%3A1353103.md).
- Alternate submission paths (embedded forms, API, mobile) skipping 2FA, rate limit, or blacklist [E3](https://bugbountylibrary.com/r/h1%3A418767.md).
- Sibling endpoints of one resource (submit vs update_checkout) where only one enforces the permission [E6](https://bugbountylibrary.com/r/h1%3A423546.md).

## How to review
For every state-changing route, list the checks the canonical path applies (auth, 2FA, CSRF, policy, rate limit) and confirm the route applies the same set. Treat CSRF and auth as separate checks: a route can have auth and still lack CSRF [E1](https://bugbountylibrary.com/r/h1%3A1122408.md)[E4](https://bugbountylibrary.com/r/h1%3A416978.md)[E5](https://bugbountylibrary.com/r/h1%3A1353103.md). Confirm no state-changing action is reachable by GET; if it is, require a token or reject the method. For setup handlers, require a positive guard: refuse the action whenever setup is complete, regardless of other parameters. For file sinks, validate ids against an allowlist with no path separators. Invariant: no state-changing route is reachable without the full check set its siblings enforce, and no state change happens on a method that carries no token.

## Variants seen
- Boolean logic error in setup guard (`&&` where `||` intended) enabling re-run of privileged setup [E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-logic-flaw-leading-to-rce-in-dynamicweb-9-5-0-9-12-7.md).
- GraphQL mutations accepted via GET, bypassing POST-only CSRF [E1](https://bugbountylibrary.com/r/h1%3A1122408.md).
- State-changing GET behind a login-redirect link, no CSRF token [E4](https://bugbountylibrary.com/r/h1%3A416978.md).
- Missing CSRF + auth on a dev destroy route with path traversal into file deletion [E5](https://bugbountylibrary.com/r/h1%3A1353103.md).
- Alternate submission endpoint omitting 2FA and blacklist [E3](https://bugbountylibrary.com/r/h1%3A418767.md).
- Sibling checkout endpoint skipping the permission check [E6](https://bugbountylibrary.com/r/h1%3A423546.md).

## Impact and severity
Led to unauthenticated admin creation and webshell upload (RCE) [E2](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-logic-flaw-leading-to-rce-in-dynamicweb-9-5-0-9-12-7.md), arbitrary file deletion on developer machines [E5](https://bugbountylibrary.com/r/h1%3A1353103.md), domain/DNS takeover of a store [E4](https://bugbountylibrary.com/r/h1%3A416978.md), and policy bypass (2FA, blacklist, checkout permission) [E3](https://bugbountylibrary.com/r/h1%3A418767.md)[E6](https://bugbountylibrary.com/r/h1%3A423546.md). Severity is highest when the route reaches a shell or filesystem sink or creates privileged accounts; worse when reachable cross-origin or without any credential.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1122408.md
- E2: https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-logic-flaw-leading-to-rce-in-dynamicweb-9-5-0-9-12-7.md
- E3: https://bugbountylibrary.com/r/h1%3A418767.md
- E4: https://bugbountylibrary.com/r/h1%3A416978.md
- E5: https://bugbountylibrary.com/r/h1%3A1353103.md
- E6: https://bugbountylibrary.com/r/h1%3A423546.md
