bx-csrf
bx-csrf: CSRF Protection
Installation
install-bx-module bx-csrf
# CommandBox
box install bx-csrf
BIFs
| BIF | Description |
|---|---|
CSRFGenerateToken( [key], [forceNew] ) |
Generate a CSRF token (optionally scoped to a key) |
CSRFVerifyToken( token, [key] ) |
Verify a CSRF token (returns boolean) |
CSRFHiddenField( [key], [forceNew] ) |
Generate a ready-to-embed <input type="hidden"> HTML field |
CSRFRotate() |
Rotate/invalidate all current tokens, forcing regeneration |
Basic Form Protection
<!-- In your form template -->
<form method="POST" action="/submit">
<!-- Embed the token as a hidden field -->
<bx:output>#CSRFHiddenField()#</bx:output>
<!-- Renders: <input type="hidden" name="csrf" value="...token..."> -->
<input type="text" name="email" />
<button type="submit">Submit</button>
</form>
// In your form handler
function processForm() {
// Verify the submitted token
if ( !CSRFVerifyToken( form.csrf ) ) {
throw( type: "Security.CSRFTokenInvalid", message: "Invalid CSRF token" )
}
// Safe to process form data
// ...
}
Scoped Tokens (Per-Form)
Use scoped tokens when you have multiple forms on the same page or need per-action tokens:
// Generate a scoped token (named "deleteUser")
token = CSRFGenerateToken( "deleteUser" )
// Verify the scoped token
if ( !CSRFVerifyToken( form.csrf, "deleteUser" ) ) {
throw( type: "Security.CSRFTokenInvalid", message: "Invalid delete token" )
}
<!-- Scoped hidden field -->
<bx:output>#CSRFHiddenField( "deleteUser" )#</bx:output>
AJAX / API Requests (Header-Based)
// Client-side: include token in X-CSRF-Token header
// fetch("/api/update", {
// method: "POST",
// headers: { "X-CSRF-Token": csrfToken },
// body: JSON.stringify(data)
// })
// Server-side: auto-verification (configure in boxlang.json)
// Or manually:
if ( !CSRFVerifyToken( getHTTPRequestData().headers[ "X-CSRF-Token" ] ?: "" ) ) {
throw( type: "Security.CSRFTokenInvalid", message: "Missing or invalid CSRF token" )
}
Token Rotation
// Rotate all tokens (e.g., after login/logout)
CSRFRotate()
// All existing tokens are immediately invalidated
// Next call to CSRFGenerateToken() creates a fresh token
Configuration (boxlang.json)
{
"modules": {
"csrf": {
"settings": {
"cacheStorage" : "session", // Cache for token storage (default: session)
"rotationInterval" : 30, // Token lifetime in minutes (0 = never expire)
"timeoutSkew" : 120, // Seconds before expiry to force-rotate
"reapFrequency" : 1, // Minutes between expired-token cleanup
"autoVerify" : false, // Auto-verify tokens on state-changing requests
"headerName" : "x-csrf-token",
"verifyMethods" : ["POST", "PUT", "PATCH", "DELETE"]
}
}
}
}
Auto-Verification
When autoVerify: true, every POST/PUT/PATCH/DELETE request is automatically checked for a valid CSRF token in the x-csrf-token header. No manual verification code needed.
Common Pitfalls
- ✅ Always include the CSRF token for any state-changing request (POST, PUT, DELETE, PATCH)
- ❌ GET requests should NEVER change state — CSRF protection only applies to non-GET methods
- ✅ Use scoped tokens (
keyparam) to differentiate between multiple forms on the same page - ❌ Don't skip
CSRFRotate()after login/logout — stale tokens from old sessions are a risk - ✅ For SPA/AJAX apps, retrieve the token server-side and embed it in the page on initial render
More from ortus-boxlang/skills
boxlang-functional-programming
Use this skill when working with BoxLang lambdas, closures, arrow functions, higher-order functions, functional array/struct pipelines (map, filter, reduce, flatMap, groupBy, etc.), destructuring, or spread syntax.
10boxlang-code-reviewer
Use this skill when reviewing BoxLang code for quality, correctness, security vulnerabilities, performance issues, style violations, or when providing structured code review feedback following BoxLang best practices and security guidelines.
9boxlang-best-practices
Use this skill when writing, reviewing, or improving BoxLang code to ensure it follows community best practices for naming, structure, scoping, error handling, performance, and maintainability.
9boxlang-classes-and-oop
Use this skill when writing BoxLang classes, components, interfaces, inheritance hierarchies, annotations, properties, constructors, or applying object-oriented design patterns in BoxLang.
9boxlang-web-development
Use this skill when building BoxLang web applications: Application.bx lifecycle, request/response handling, sessions, forms, REST APIs, HTTP clients, routing, CSRF protection, Server-Sent Events, or configuring CommandBox/MiniServer.
8boxlang-configuration
Use this skill when configuring BoxLang runtime settings via boxlang.json, setting environment variables for config overrides, configuring datasources, caches, executors, modules, logging, security, or schedulers — or when helping someone understand the BoxLang configuration system.
8