Add the cors-csrf module
This commit is contained in:
77
cors-csrf/docs/08-debugging-recipes.md
Normal file
77
cors-csrf/docs/08-debugging-recipes.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 8. Debugging recipes
|
||||
|
||||
*Prev: [7. SameSite](07-samesite.md)*
|
||||
|
||||
## Turn on the two log categories first
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
level:
|
||||
org.springframework.web.cors: DEBUG # DefaultCorsProcessor's Skip:/Reject: lines
|
||||
org.springframework.security.web.csrf: DEBUG # "Invalid CSRF token found for ..."
|
||||
```
|
||||
|
||||
Almost every question in this subject is answered by one line from one of those two.
|
||||
|
||||
## Reproduce the preflight without a browser
|
||||
|
||||
```bash
|
||||
curl -s -i -X OPTIONS http://localhost:8080/api/data \
|
||||
-H 'Origin: https://spa.example.com' \
|
||||
-H 'Access-Control-Request-Method: POST' \
|
||||
-H 'Access-Control-Request-Headers: content-type,x-xsrf-token'
|
||||
```
|
||||
|
||||
That is the whole preflight. `scripts/preflight.sh` wraps it. Note the absence of `-u` and
|
||||
`-b`: the browser sends no credentials on a preflight, and reproducing it *with* credentials
|
||||
hides the bug.
|
||||
|
||||
## Is `CorsFilter` even in the chain?
|
||||
|
||||
```bash
|
||||
curl -s localhost:8080/diag/chain | python3 -m json.tool
|
||||
```
|
||||
|
||||
If `CorsFilter` is absent, no amount of MVC configuration will help — chapter 1. The
|
||||
production equivalent, without a diagnostic endpoint, is the startup log:
|
||||
|
||||
```
|
||||
Will secure any request with filters: DisableEncodeUrlFilter, ..., CorsFilter, ...
|
||||
```
|
||||
|
||||
Grep for `with filters:`.
|
||||
|
||||
## Which `CorsConfigurationSource` beans exist, and what are they called?
|
||||
|
||||
```bash
|
||||
curl -s localhost:8080/diag/cors-sources
|
||||
```
|
||||
|
||||
`hasBeanNamedCorsConfigurationSource: false` with a `UrlBasedCorsConfigurationSource` in the list
|
||||
is the chapter 2 failure exactly.
|
||||
|
||||
## Read the status code as a diagnosis
|
||||
|
||||
| Symptom | Look at |
|
||||
|---|---|
|
||||
| Preflight `401`/`403`, no CORS headers | Chapter 1 — no `CorsFilter` |
|
||||
| Preflight `200`, no CORS headers | Chapter 2 — bean name |
|
||||
| Preflight `403`, `Invalid CORS request` | Chapter 3 — read the DEBUG line |
|
||||
| `401` on a request with valid credentials | Chapter 5 — the `/error` dispatch |
|
||||
| `403` on a POST, `GET` is fine | Chapter 6 — CSRF |
|
||||
| Cookie visible in DevTools' response, absent from the jar | Chapter 7 — `SameSite=None` with no `Secure` |
|
||||
| Every request preflights, latency doubled | Chapter 1 — no `Access-Control-Max-Age` |
|
||||
|
||||
## Check the cookie jar, not the response
|
||||
|
||||
DevTools shows the `Set-Cookie` header in the Network tab whether or not the browser stored the
|
||||
cookie. Application → Cookies is the jar. A header present in one and absent from the other
|
||||
is chapter 7, every time.
|
||||
|
||||
## Delete the diagnostic endpoints
|
||||
|
||||
`DiagController` and `CookieSpecReport` publish your filter chain and bean names. They exist to
|
||||
make this repository legible. Do not ship them.
|
||||
|
||||
---
|
||||
*Prev: [7. SameSite](07-samesite.md)*
|
||||
Reference in New Issue
Block a user