feat(security): HttpOnly cookies + CSP headers + CSRF double-submit protection
- Migrate auth tokens from localStorage to HttpOnly SameSite=Lax cookies - Add cookie_auth.rs: helpers for setting/clearing auth + CSRF cookies - Update auth middleware: 3-method auth (Bearer → Basic → Cookie) - Add 5 security headers: CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy - Implement CSRF double-submit cookie pattern (csrf.rs middleware) - Set CSRF cookie on login/refresh/oidc-exchange, clear on logout - CookieAuthenticated marker skips CSRF for Bearer/Basic clients - Frontend: strip all localStorage token refs from 14 JS files - Frontend: csrf.js utility + all 52 mutating fetch/XHR calls protected - 121 tests passing, 0 warnings
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* CSRF double-submit cookie utility.
|
||||
*
|
||||
* Reads the `oxicloud_csrf` cookie (which is NOT HttpOnly) and provides
|
||||
* its value as the `X-CSRF-Token` header on mutating requests.
|
||||
*
|
||||
* Usage:
|
||||
* // In any fetch call that changes state:
|
||||
* fetch(url, { method: 'POST', headers: { ...getCsrfHeaders(), 'Content-Type': 'application/json' } })
|
||||
*
|
||||
* The server-side `csrf_middleware` validates that the header value matches
|
||||
* the cookie for every POST/PUT/DELETE/PATCH request authenticated via
|
||||
* HttpOnly cookies.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function getCsrfToken() {
|
||||
const match = document.cookie
|
||||
.split('; ')
|
||||
.find(row => row.startsWith('oxicloud_csrf='));
|
||||
return match ? match.split('=')[1] : '';
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function getCsrfHeaders() {
|
||||
const token = getCsrfToken();
|
||||
return token ? { 'X-CSRF-Token': token } : {};
|
||||
}
|
||||
Reference in New Issue
Block a user