Datasette ditches CSRF tokens for Sec-Fetch-Site
Simon Willison's Datasette just swapped token-based CSRF protection for header checks—Claude did the grunt work, but the implications run deeper.
Datasette just merged PR #2689, ripping out token-based CSRF protection in favor of Sec-Fetch-Site header checks. This isn't incremental improvement. It's a pattern shift that deletes entire classes of developer friction.
What changed
For years, Datasette used CSRF tokens via Simon Willison's asgi-csrf library. Every form needed a hidden input field. Every API endpoint required selective exemptions. The machinery worked, but it leaked implementation details everywhere.
The new approach: check the Sec-Fetch-Site header. If a request comes from a different site, reject it unless explicitly allowed. No tokens. No hidden fields. No per-endpoint carve-outs.
This follows Filippo Valsorda's August 2025 research and Go 1.25's implementation from the same month. The browser sends Sec-Fetch-Site automatically. JavaScript from a different origin can't fake it. The security model collapses to: trust same-site requests, scrutinize everything else.
Why this matters beyond Datasette
CSRF tokens are security-by-ritual. You scatter them through templates, wire up validation middleware, document which endpoints need exemptions. The cognitive load compounds as projects grow.
Header-based protection inverts this. The browser does the work. Your application checks one header. APIs become same-site-by-default without annotation. Cross-origin requests require explicit opt-in via CORS, which you probably configured anyway.
The shift mirrors a broader pattern: moving security checks from application logic to protocol primitives. Content Security Policy replaced inline script filtering. SameSite cookies replaced complex CSRF token schemes for session cookies. Now Sec-Fetch-Site handles the rest.
The AI collaboration detail
Claude Code wrote most of the implementation across 10 commits. Simon guided it closely and cross-checked with GPT-5.4. Then he wrote the PR description by hand.
That last part matters. AI can refactor 10 files and update test suites faster than any human. But the decision to switch protection models, the risk assessment, the "is this actually better" judgment—that's still human work. Simon's note about writing descriptions manually "to keep myself honest" recognizes this boundary.
We're settling into a division of labor: AI handles mechanical transformation, humans own architectural choices and their explanations. The PR itself is a collaboration. The accountability stays singular.
Datasette's change won't make headlines, but it's a marker. When mature projects swap out foundational security patterns, it signals the new approach has crossed from research to production-ready. Go shipped it in 1.25. Datasette ships it now. Your framework is probably next. The era of sprinkling CSRF tokens through templates is ending—not because tokens failed, but because browsers finally offer something simpler.