Security
Bosia includes several security features enabled by default.
CSRF Protection
Section titled “CSRF Protection”All non-safe requests (POST, PUT, PATCH, DELETE) are validated against the server’s origin. This uses the same approach as SvelteKit — checking the Origin or Referer header.
- Safe methods (GET, HEAD, OPTIONS) are exempt
- Missing
Origin/Refereron state-changing requests is rejected with 403 - Cross-origin requests from unexpected origins are blocked
Configuration
Section titled “Configuration”Allow additional origins via the CSRF_ALLOWED_ORIGINS environment variable:
CSRF_ALLOWED_ORIGINS=https://app.example.com, https://mobile.example.comCORS is disabled by default. Enable it by setting allowed origins:
CORS_ALLOWED_ORIGINS=https://app.example.com, https://admin.example.comAdditional CORS settings:
CORS_ALLOWED_METHODS=GET, POST, PUT, DELETECORS_ALLOWED_HEADERS=Content-Type, AuthorizationCORS_EXPOSED_HEADERS=X-Request-IdCORS_CREDENTIALS=trueCORS_MAX_AGE=86400Preflight OPTIONS requests are handled automatically when CORS is configured.
Security Headers
Section titled “Security Headers”Bosia sets these headers on every response:
| Header | Value |
|---|---|
X-Content-Type-Options | nosniff |
X-Frame-Options | SAMEORIGIN |
Referrer-Policy | strict-origin-when-cross-origin |
Cookie Security
Section titled “Cookie Security”The cookie API includes several protections:
- Header injection prevention — values containing
;,\r, or\nare rejected - SameSite validation — only
Strict,Lax, orNoneare accepted - Automatic encoding — cookie values are safely encoded with
encodeURIComponent
Set secure cookie options:
event.cookies.set("session", token, { path: "/", httpOnly: true, // not accessible via JavaScript secure: true, // HTTPS only sameSite: "Lax", // protects against CSRF maxAge: 60 * 60 * 24 * 7, // 7 days});XSS Protection
Section titled “XSS Protection”JSON data embedded in server-rendered HTML is escaped using a safe serializer that:
- Escapes
<,>,&,',", and Unicode characters that could break out of script tags - Handles circular references gracefully
Request Body Limits
Section titled “Request Body Limits”Request body size is limited by default to prevent denial-of-service:
BODY_SIZE_LIMIT=512K # defaultBODY_SIZE_LIMIT=1M # 1 megabyteBODY_SIZE_LIMIT=10M # 10 megabytesBODY_SIZE_LIMIT=Infinity # no limit (not recommended)Supports K (kilobytes), M (megabytes), and G (gigabytes) suffixes.
Path Traversal Protection
Section titled “Path Traversal Protection”Static file and prerendered page serving validates that resolved file paths stay within their allowed directories, preventing ../ traversal attacks.
Production Error Handling
Section titled “Production Error Handling”In production (NODE_ENV=production), stack traces are stripped from error responses to prevent leaking internal details to clients.