You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md
+31-6Lines changed: 31 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -183,8 +183,9 @@ For the rare cases of outdated or embedded browsers that lack `Sec-Fetch-*` supp
183
183
`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).
184
184
**Policy (high level)**
185
185
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`.
188
189
189
190
```JavaScript
190
191
constSAFE=newSet(['GET','HEAD','OPTIONS']);
@@ -195,7 +196,30 @@ For the rare cases of outdated or embedded browsers that lack `Sec-Fetch-*` supp
195
196
}
196
197
```
197
198
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).
199
223
200
224
```JavaScript
201
225
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
211
235
}
212
236
```
213
237
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.
215
239
216
240
2. If `Sec-Fetch-*` headers are absent: choose a fallback based on risk and compatibility requirements:
217
241
2.1. Fail-safe (recommended for sensitive endpoints): treat absence as unknown and block the request.
218
242
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).
219
243
220
244
3. Additional options
221
-
3.1 To ensure that your site can still be linked from other sites, you have to allow simple (HTTPGET) top-level navigation.
245
+
246
+
3.1 To ensure that your site can still be linked from other sites, you have to allow simple (HTTPGET) top-level navigation.
222
247
223
248
```JavaScript
224
249
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
229
254
}
230
255
```
231
256
232
-
3.2 Whitelist explicit cross-origin flows. If certain endpoints intentionally accept cross-origin requests (CORSJSON 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 (CORSJSON 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.
0 commit comments