Skip to content

Commit 9813b91

Browse files
authored
Update Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md
state-changing safe methods requests clarification
1 parent 189cb71 commit 9813b91

File tree

1 file changed

+31
-6
lines changed

1 file changed

+31
-6
lines changed

cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ For the rare cases of outdated or embedded browsers that lack `Sec-Fetch-*` supp
183183
`Sec-Fetch-Site` is the most useful Fetch Metadata header for blocking CSRF-like cross-origin requests and should be the primary signal in a Fetch-Metadata-based policy. Use other Fetch Metadata headers (`Sec-Fetch-Mode`, `Sec-Fetch-Dest`, `Sec-Fetch-User`) to further refine or tailor policies to your application's needs (for example, allowing top-level navigation requests or permitting specific Dest values for resource endpoints).
184184
**Policy (high level)**
185185

186-
1. If `Sec-Fetch-Site` is present:
187-
1.1. Treat cross-site as untrusted for state-changing actions. By default, reject non-safe methods (POST / PUT / PATCH / DELETE) when `Sec-Fetch-Site: cross-site`.
186+
1. If `Sec-Fetch-Site` is present
187+
188+
1.1. Treat cross-site as untrusted for state-changing actions. By default, reject non-safe methods (POST / PUT / PATCH / DELETE) when `Sec-Fetch-Site: cross-site`.
188189

189190
```JavaScript
190191
const SAFE = new Set(['GET','HEAD','OPTIONS']);
@@ -195,7 +196,30 @@ For the rare cases of outdated or embedded browsers that lack `Sec-Fetch-*` supp
195196
}
196197
```
197198

198-
1.2. Allow `same-origin`. Treat `same-site` as allowed only if your threat model trusts sibling subdomains; otherwise handle `same-site` conservatively (for example, require additional validation).
199+
1.2 If your application relies on [safe HTTP methods](https://developer.mozilla.org/en-US/docs/Glossary/Safe/HTTP) (GET, HEAD, or OPTIONS) for state‑changing actions, you should explicitly reflect that in your policy – e.g., by requiring a Fetch‑Metadata header review for requests to those endpoints. This can be enforced with a policy rule like:
200+
201+
```JavaScript
202+
const SAFE_METHODS = new Set(['GET','HEAD','OPTIONS']);
203+
const SENSITIVE_ENDPOINTS = new Set([
204+
'/user/profile',
205+
'/account/details',
206+
]);
207+
208+
const site = req.get('Sec-Fetch-Site');
209+
const path = req.path;
210+
211+
// Block if cross-site + sensitive endpoint
212+
if (site === 'cross-site' && SENSITIVE_ENDPOINTS.has(path)) {
213+
return false;
214+
}
215+
216+
// Block if cross-site + unsafe method
217+
if (site === 'cross-site' && !SAFE_METHODS.has(req.method)) {
218+
return false;
219+
}
220+
```
221+
222+
1.3. Allow `same-origin`. Treat `same-site` as allowed only if your threat model trusts sibling subdomains; otherwise handle `same-site` conservatively (for example, require additional validation).
199223

200224
```JavaScript
201225
const trustSameSite = false; // set true only if you trust sibling subdomains
@@ -211,14 +235,15 @@ For the rare cases of outdated or embedded browsers that lack `Sec-Fetch-*` supp
211235
}
212236
```
213237

214-
1.3. Allow none for user-driven top-level navigations (bookmarks, typed URLs, explicit form submits) where appropriate.
238+
1.4. Allow none for user-driven top-level navigations (bookmarks, typed URLs, explicit form submits) where appropriate.
215239

216240
2. If `Sec-Fetch-*` headers are absent: choose a fallback based on risk and compatibility requirements:
217241
2.1. Fail-safe (recommended for sensitive endpoints): treat absence as unknown and block the request.
218242
2.2. Fail-open (compatibility-first): fallback to other security measure ([standard origin verification](#using-standard-headers-to-verify-origin), CSRF tokens, and/or require additional validation).
219243

220244
3. Additional options
221-
3.1 To ensure that your site can still be linked from other sites, you have to allow simple (HTTP GET) top-level navigation.
245+
246+
3.1 To ensure that your site can still be linked from other sites, you have to allow simple (HTTP GET) top-level navigation.
222247

223248
```JavaScript
224249
if (req.get('Sec-Fetch-Mode') === 'navigate' &&
@@ -229,7 +254,7 @@ For the rare cases of outdated or embedded browsers that lack `Sec-Fetch-*` supp
229254
}
230255
```
231256

232-
3.2 Whitelist explicit cross-origin flows. If certain endpoints intentionally accept cross-origin requests (CORS JSON APIs, third-party integrations, webhooks), explicitly exempt those endpoints from the global Sec-Fetch deny policy and secure them with proper CORS configuration, authentication, and logging.
257+
3.2 Whitelist explicit cross-origin flows. If certain endpoints intentionally accept cross-origin requests (CORS JSON APIs, third-party integrations, webhooks), explicitly exempt those endpoints from the global Sec-Fetch deny policy and secure them with proper CORS configuration, authentication, and logging.
233258

234259
### Requirements
235260

0 commit comments

Comments
 (0)