Protect an account change from a forged request

An account settings handler trusts the session cookie even when another site causes the request. Repair the request policy and preserve legitimate settings updates.

Requires Node.js 22 or newer. No package installation or server needed. To work in a container instead, open the folder with VS Code Dev Containers or GitHub Codespaces: .devcontainer/devcontainer.json uses the Dev Containers Node.js 24 image, pinned by digest.
1. Unzip all files into one folder.
2. In that folder, run: node --test exercise.test.mjs
3. Edit request-policy.mjs, then run the same command again.

The starter deliberately fails some tests. A successful repair passes every case, including cases that catch common wrong fixes. The browser runs this same cases.mjs with the same fixtures; locally Node runs your code directly. If you completed the optional first stage in the browser, Download my work adds your input as stage1-input.json and the tests include it. Only run code you wrote or reviewed.

1. Reproduce the change
Run the starter. The cross-origin POST carries a valid session and returns true. The harness models an authorization decision; it does not make a live browser request or mutate an account.

2. Bind the request
Reject missing sessions and unsupported methods. Require the exact origin https://app.example. Missing and null origins are rejected by this application’s contract.

3. Bind the token
Require a nonempty trusted session token and compare request.csrfToken with session.csrfToken. The other-session case submits session-B-secret while the current session expects session-A-secret, so it must return false.

4. Exercise legitimate use
POST, PUT, PATCH and DELETE from the trusted origin with session-A-secret return true. Cross-origin, wrong-token, missing-token, missing-origin and GET cases return false. Blocking every request breaks the legitimate cases.

SUPPLIED CONTRACT
allowChange(request, session) receives a normalized method, the browser Origin header, a submitted CSRF token, and a trusted session with csrfToken. This endpoint changes state only with POST, PUT, PATCH or DELETE; it rejects every other method. Its one allowed origin is https://app.example. No cross-origin clients are supported.

REFERENCE
reference.mjs contains an explained solution: The decision is a conjunction. A valid session alone is insufficient; a trusted origin alone is insufficient; equality of two missing token values is insufficient. The supplied matching session-A-secret supports each declared mutation method. A wrong-session token fails because B-secret differs from A-secret. These booleans model the guard before persistence, so a real route must also prove false prevents its state change.

SCOPE
This is the server policy function exercised with HTTP-shaped fixtures, not a browser attack against a live server. Use a framework CSRF implementation, HTTPS, appropriate cookie settings and unpredictable server-generated tokens in production. XSS can act within the trusted origin and needs separate controls.

NEXT TASK
Find every state-changing route in your application. Which middleware applies this policy, and are any GET routes accidentally mutating data?

SOURCE
https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
