Challenge Overview#
- Challenge Name: SameSite Lax bypass via method override
- Category: Cross-Site Request Forgery (CSRF) / Client-Side Security
- Level: Practitioner
- Target Endpoint:
POST /my-account/change-email - Provided Credentials:
wiener:peter - Objective: Bypass browser-enforced
SameSite=Laxcookie protections by exploiting an HTTP method override vulnerability, converting the state-changing action into a top-levelGETnavigation to change the victim’s email address.
1. Core Fundamentals#
1.1. The Modern Browser Cookie Landscape: SameSite Attribute#
In response to widespread Cross-Site Request Forgery (CSRF) vulnerabilities, major browser vendors standardized and deployed the SameSite cookie attribute.
The SameSite directive controls whether a cookie is transmitted along with cross-site HTTP requests, operating under three distinct modes:
SameSite=Strict: Cookies are never transmitted in any cross-site context. Even when a user clicks a legitimate link from an external domain or email client, the cookie is withheld.SameSite=None: Cookies are sent in all cross-site contexts (provided theSecureflag is enabled). This represents legacy browser behavior.SameSite=Lax(Default Browser Baseline): Cookies are withheld on cross-site subrequests (e.g.,<img>,<iframe>,fetch(),<script>, and cross-site<form method="POST">submissions). However, they are explicitly sent on Top-Level Navigations using safe HTTP methods (specificallyGET).
| |
1.2. The Developer Assumption: “Lax Killed CSRF”#
Because modifying sensitive account details (such as email addresses or passwords) is conventionally performed via HTTP POST requests, many development teams have abandoned server-side Anti-CSRF tokens under the belief that:
“Since modern browsers default to
SameSite=Lax, cross-site POST form submissions will never carry the victim’s session cookie. Therefore, CSRF protection is automatically enforced by the browser.”
This lab exposes the fatal flaw in relying solely on browser-level transport heuristics without application-level validation.
1.3. The Mechanism of HTTP Method Overriding (Method Spoofing)#
Historically, standard HTML forms only supported GET and POST methods. To support RESTful API architectures requiring PUT, DELETE, or PATCH, web frameworks (including Symfony, Ruby on Rails, Laravel, and Express via method-override) introduced HTTP Method Overriding.
Under this mechanism, clients transmit an override directive via:
- A custom header:
X-HTTP-Method-Override: PUT - A URL query parameter or form body field:
_method=PUT
The Architectural Vulnerability:#
When method-override middleware is configured insecurely, it allows clients to override a GET request into a POST request on the backend:
| |
This architectural discrepancy creates an exploitable divergence:
- The Browser sees: A top-level
GETnavigation $\rightarrow$ Attaches theSameSite=Laxsession cookie. - The Backend Middleware sees: An incoming
_method=POSTdirective $\rightarrow$ Treats the request as aPOSTand executes the mutation.
1.4. The CSRF Preconditions Matrix#
| |
2. Attack Architecture / Threat Model#
2.1. Trust Boundaries & Behavioral Divergence#
The vulnerability exploits a fundamental asymmetry between browser-level transport rules and backend application routing:
- Browser Trust Boundary: The browser enforces
SameSite=Laxbased exclusively on the outward HTTP transport verb (GET) and top-level navigation context. - Server Middleware Boundary: The application middleware inspects query parameters before routing, overriding the request method internally to
POSTwithout re-verifying cross-origin origin headers (Origin,Sec-Fetch-Site).
2.2. Attack Flow Diagram#
| |
2.3. Root Cause Analysis#
- Permissive Method-Override Configuration: The middleware blindly parses
_method=POSTfrom incomingGETrequests rather than restricting overrides exclusively toPOSTpayloads (PUT,DELETE,PATCH). - Absence of Anti-CSRF Tokens: The backend relies entirely on
SameSite=Laxtransport heuristics and enforces no cryptographic Synchronizer Tokens on state-changing controllers.
3. Vulnerability Exploitation#
Phase 1: Baseline Request & Defense Surface Analysis#
We authenticate as wiener:peter and intercept the legitimate email-change transaction using Burp Suite Proxy / Repeater:

| |
Observations:#
- The request contains no Anti-CSRF token.
- The application relies entirely on browser-enforced
SameSite=Laxcookies to block cross-site POST attacks. - If an attacker attempts a standard
<form method="POST">fromexploit-server.net, modern browsers will withholdsession=a0JDk..., causing the attack to fail.
Phase 2: Testing Direct GET Mutation Rejection#
In Burp Repeater, we convert the request to a standard GET request:

| |
Server Response:#
| |
Analysis:#
The server actively enforces REST verb boundaries: direct GET requests are rejected with 405 Method Not Allowed and an explicit Allow: POST header.
Phase 3: Discovering Method Override in Burp Repeater#
We test whether the application’s routing layer supports HTTP Method Overriding via query parameter spoofing. We append &_method=POST to the URL:

| |
Server Response:#
| |
Critical Breakthrough:#
The server accepts the request and returns HTTP/2 302 Found!
The presence of _method=POST instructed the backend middleware to rewrite the request method internally from GET to POST, successfully executing the email change to wiener321@gmail.com.
Phase 4: Weaponizing the Exploit on Exploit Server#
We navigate to PortSwigger’s Exploit Server (https://exploit-...exploit-server.net/exploit) and craft the payload:

Exploit Server Payload Configuration:#
- File:
/exploit - Head:
1 2HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 - Body:
1 2 3 4 5<form action="https://0a8b009e039fa730807f352200a700c9.web-security-academy.net/my-account/change-email" method="GET"> <input type="hidden" name="email" value="tuki123@gmail.com"> <input type="hidden" name="_method" value="POST"> </form> <script>document.forms[0].submit();</script>
Detailed Breakdown of Exploit Mechanics:#
method="GET":- This is the core bypass mechanism. Setting
method="GET"triggers a Top-Level Navigation. - Under standard
SameSite=Laxbrowser specifications, the browser attaches the victim’s session cookie to top-level GET navigations. - Had
method="POST"been used, the browser would have stripped the cookie immediately.
- This is the core bypass mechanism. Setting
action=".../my-account/change-email":- Points to the target endpoint on the vulnerable application.
- The Hidden Input Elements:
<input type="hidden" name="email" value="tuki123@gmail.com">: Supplies the attacker’s email to overwrite the victim’s account.<input type="hidden" name="_method" value="POST">: Serialized into the URL query string upon submission, providing the method-override instruction to the backend.
document.forms[0].submit();:- Automatically executes the submission as soon as the DOM renders, delivering a zero-click exploit.
Phase 5: Delivering Exploit to Victim & Verification#
- Click Store to persist the payload at
/exploit. - Click Deliver exploit to victim.

Execution Flow & Lab Resolution:#
- The automated victim bot (holding an active authenticated session with
SameSite=Laxcookies) accesses/exploit. - The bot’s browser parses the HTML and executes
document.forms[0].submit(). - The browser dispatches a cross-site top-level navigation:
1GET /my-account/change-email?email=tuki123@gmail.com&_method=POST - Because the transport method is
GET, the browser includes the victim’ssessioncookie despite the cross-origin context. - The target application’s method-override middleware intercepts the request, reads
_method=POST, and mutates the internal request verb toPOST. - The account controller processes the request as a valid
POST, updating the victim’s email totuki123@gmail.com. - PortSwigger confirms the email modification on the victim account and awards the LAB Solved status (Figure 5).
4. Remediation Strategies#
Remediating this vulnerability requires hardening method-override routing logic, enforcing cryptographic tokens, and configuring strict cookie policies.
| |
4.1. Restrict Method Overriding to POST Requests Only (Primary Fix)#
Method overriding should never be permitted on incoming GET requests. It should only be used to map POST requests to RESTful verbs (PUT, DELETE, PATCH):
| |
4.2. Enforce Cryptographic Anti-CSRF Tokens#
Do not treat SameSite=Lax as a standalone replacement for Anti-CSRF tokens. Critical state-changing endpoints must implement the Synchronizer Token Pattern:
| |
Even if an attacker bypasses SameSite=Lax via a top-level GET navigation, the request will be rejected by the server due to the missing or invalid CSRF token (403 Forbidden).
4.3. Configure SameSite=Strict for Critical Session Cookies#
For applications handling sensitive user data, configure the session cookie with SameSite=Strict:
| |
Under SameSite=Strict, the browser withholds the cookie even on top-level GET navigations, completely neutralizing this attack vector.
4.4. Mandatory Re-Authentication for Sensitive Operations#
Require users to provide their current password or complete MFA verification before committing sensitive profile changes. This prevents unauthorized mutations regardless of transport-level bypasses.
