CSRF Protection
This middleware protects against CSRF attacks by checking both the Origin
header and the Sec-Fetch-Site
header. The request is allowed if either validation passes.
The middleware only validates requests that:
- Use unsafe HTTP methods (not GET, HEAD, or OPTIONS)
- Have content types that can be sent by HTML forms (
application/x-www-form-urlencoded
,multipart/form-data
, ortext/plain
)
Old browsers that do not send Origin
headers, or environments that use reverse proxies to remove these headers, may not work well. In such environments, use other CSRF token methods.
Import
import { Hono } from 'hono'
import { csrf } from 'hono/csrf'
Usage
const app = new Hono()
// Default: both origin and sec-fetch-site validation
app.use(csrf())
// Allow specific origins
app.use(csrf({ origin: 'https://myapp.example.com' }))
// Allow multiple origins
app.use(
csrf({
origin: [
'https://myapp.example.com',
'https://development.myapp.example.com',
],
})
)
// Allow specific sec-fetch-site values
app.use(csrf({ secFetchSite: 'same-origin' }))
app.use(csrf({ secFetchSite: ['same-origin', 'none'] }))
// Dynamic origin validation
// It is strongly recommended that the protocol be verified to ensure a match to `$`.
// You should *never* do a forward match.
app.use(
'*',
csrf({
origin: (origin) =>
/https:\/\/(\w+\.)?myapp\.example\.com$/.test(origin),
})
)
// Dynamic sec-fetch-site validation
app.use(
csrf({
secFetchSite: (secFetchSite, c) => {
// Always allow same-origin
if (secFetchSite === 'same-origin') return true
// Allow cross-site for webhook endpoints
if (
secFetchSite === 'cross-site' &&
c.req.path.startsWith('/webhook/')
) {
return true
}
return false
},
})
)
Options
optional origin: string
| string[]
| Function
Specify allowed origins for CSRF protection.
string
: Single allowed origin (e.g.,'https://example.com'
)string[]
: Array of allowed originsFunction
: Custom handler(origin: string, context: Context) => boolean
for flexible origin validation and bypass logic
Default: Only same origin as the request URL
The function handler receives the request's Origin
header value and the request context, allowing for dynamic validation based on request properties like path, headers, or other context data.
optional secFetchSite: string
| string[]
| Function
Specify allowed Sec-Fetch-Site header values for CSRF protection using Fetch Metadata.
string
: Single allowed value (e.g.,'same-origin'
)string[]
: Array of allowed values (e.g.,['same-origin', 'none']
)Function
: Custom handler(secFetchSite: string, context: Context) => boolean
for flexible validation
Default: Only allows 'same-origin'
Standard Sec-Fetch-Site values:
same-origin
: Request from same originsame-site
: Request from same site (different subdomain)cross-site
: Request from different sitenone
: Request not from a web page (e.g., browser address bar, bookmark)
The function handler receives the request's Sec-Fetch-Site
header value and the request context, enabling dynamic validation based on request properties.