Blog

Luis Majano

April 02, 2020

Spread the word


Share your thoughts

We are incredibly excited to bring you a major version of our cbcsrf module, so you can protect your ColdBox applications from cross-site request forgery vectors. This is a major overhaul of the module and it will also be part of the cbSecurity module as well.

Installation/Update

install cbcsrf
update cbcsrf

Please note that if you are upgrading from the 1.x series, make sure you read the documentation as all method signatures have been updated.

What is this module for?

A module that protects you against CSRF attacks by generating unique FORM/client tokens and providing your ColdBox application with new functions for verifying these tokens.

Even though every CFML engine offers these functions natively, we have expanded them and have made them more flexible and more secure than the native CFML functions.

Features

  • Ability to generate security tokens based on your session
  • Automatic token rotation when leveraging cbauth login and logout operations
  • Ability to on-demand rotate all security tokens for specific users
  • Leverages cbStorages to store your tokens in CacheBox, which can be easily distributed and clustered
  • Ability to create multiple tokens via unique reference keys
  • Auto-verification interceptor that will verify all non-GET operations to ensure a security token is passed via rc or headers
  • Auto-sensing of integration testing so the verifier can allow testing calls
  • Token automatic rotation on specific time periods for enhance security
  • Helpers to automatically generate hidden fields for the token
  • Automatic generation endpoint that can be used for Ajax applications to request tokens for users

Settings

Below are the settings you can use for this module. Remember you must create the cbcsrf struct in your ColdBox.cfc under the moduleSettings structure:

moduleSettings = {
	cbcsrf : {
		// By default we load up an interceptor that verifies all non-GET incoming requests against the token validations
		enableAutoVerifier : true,
		// A list of events to exclude from csrf verification, regex allowed: e.g. stripe\..*
		verifyExcludes : [
		],
		// By default, all csrf tokens have a life-span of 30 minutes. After 30 minutes, they expire and we aut-generate new ones.
		// If you do not want expiring tokens, then set this value to 0
		rotationTimeout : 30,
		// Enable the /cbcsrf/generate endpoint to generate cbcsrf tokens for secured users.
		enableEndpoint : false
	}
};

Mixins

This module will add the following UDFs into any framework files:

  • csrfToken() : To generate a token, using the default or a custom key
  • csrfVerify() : Verify a valid token or not
  • csrf() : To generate a hidden field (csrf) with the token
  • csrfRotate() : To wipe and rotate the tokens for the user

Here are the method signatures:

/**
 * Provides a random token and stores it in the coldbox cache storages. You can also provide a specific key to store.
 *
 * @key A random token is generated for the key provided.
 * @forceNew If set to true, a new token is generated every time the function is called. If false, in case a token exists for the key, the same key is returned.
 *
 * @return csrf token
 */
string function csrfToken( string key='', boolean forceNew=false )
/**
 * Validates the given token against the same stored in the session for a specific key.
 *
 * @token Token that to be validated against the token stored in the session.
 * @key The key against which the token be searched.
 *
 * @return Valid or Invalid Token
 */
boolean function csrfVerify( required string token='', string key='' )
/**
 * Generate a random token and build a hidden form element so you can submit it with your form
 *
 * @key A random token is generated for the key provided.
 * @forceNew If set to true, a new token is generated every time the function is called. If false, in case a token exists for the key, the same key is returned.
 *
 * @return HTML of the hidden field (csrf)
 */
function csrf( string key='', boolean forceNew=false )
/**
 * Clears out all csrf token stored
 */
function csrfRotate()

Mappings

The module also registers the following mapping in WireBox: @cbcsrf so you can call our service model directly.

Automatic Token Expiration

By default, the module is configured to rotate all user csrf tokens every 30 minutes. This means that every token that gets created has a maximum life-span of {rotationTimeout} minutes. If you do NOT want the tokens to EVER expire during the user's logged in session, then use the value of 0 zero.

It is recommended to rotate your keys often, in case your token get's compromised.

Token Rotation

We have provided several methods to rotate or clear out all of a user's tokens. If you are using cbAuth as your module of choice for authentication, then we will listen to logins and logouts and rotate the keys for you.

If you are NOT using cbAuth then we recommend you leverage the csrfRotate() mixin or the cbsrf.rotate() method on the @cbsrf model.

function doLogin(){

	if( valid login ){
		// login user
		csrfRotate();
	}
}

function logout(){
	csrfRotate();
}

Simple Example

Below is a simple example of manually verifying tokens:

component {

    any function signUp( event, rc, prc ){
        // Store this in a hidden field in the form
        prc.token = csrfGenerate();
    }

    any function signUpProcess( event, rc, prc ){
        // Verify CSFR token from form
        if( csrfVerify( rc.token ) {
            // save form
        } else {
            // Something isn't right
            relocate( 'handler.signup' );
        }
    }
}

Automatic Token Verifier

We have included an interceptor that if loaded will verify all incoming requests to make sure the token has been passed or it will throw an exception.

The settings for this feature are:

	enableAutoVerifier : true,
	// A list of events to exclude from csrf verification, regex allowed: e.g. stripe\..*
	verifyExcludes : [
	]

You can also register an array of regular expressions that will be tested against the incoming event and if matched, it will allow the request through with no verification.

The verification process is as follows:

  • If we are doing an integration test, then skip verification
  • If the incoming HTTP Method is a get,options or head skip verification
  • If the incoming event matches any of the verifyExcludes setting, then skip verification
  • If the action is marked with a skipCsrf annotation, then skip verification
  • If no rc.csrf exists and no x-csrf-token header exists, throw a TokenNotFoundException exception
  • If the token is invalid then throw a TokenMismatchException exception

Please note that this verifier will check the following locations for the token:

  1. The request collection (rc) via the cbcsrf key
  2. The request HTTP header (x-csrf-token) key

skipCsrf Annotation

You can also annotate your event handler actions with a skipCsrf annotation and the verifier will also skip the verification process for those actions.

component{

	function doTestSave( event, rc, prc ) skipCsrf{


	}

}

/cbcsrf/generate Endpoint

This module also allows you to turn on the generation HTTP endpoint via the enableEndpoint boolean setting. When turned on the module will register the following route: GET /cbcsrf/generate/:key?. You can use this endpoint to generate tokens for your users via AJAX or UI only applications. Please note that you can pass an optional /:key URL parameter that will generate the token for that specific key.

This endpoint should be secured, so we have annotated it with a secured annotation so if you are using cbSecurity or cbGuard this endpoint will only be available to logged in users.

Add Your Comment

Recent Entries

BoxLang 1.0.0 Beta 7 Launched

BoxLang 1.0.0 Beta 7 Launched

We are pleased to announce the release of BoxLang 1.0.0-Beta 7! This latest beta version includes improvements and essential bug fixes, but more importantly it certifies the execution of ColdBox HMVC and TestBox.

What is BoxLang?

BoxLang is a modern dynamic JVM language that can be deployed on multiple runtimes: operating system (Windows/Mac/*nix/Embedded), web server, lambda, iOS, android, web assembly, and more. BoxLang combines many features from different progr

Luis Majano
Luis Majano
July 26, 2024
New BoxLang Feature: Java Method References and Higher-Order Functions

New BoxLang Feature: Java Method References and Higher-Order Functions

We’ve added more goodies to our BoxLang Java interop: method references and higher-order functions. CFML has never let you do these things, making Java Interop feel like a second-class citizen. But with BoxLang, we’re elevating Java integration to a new level.

Maria Jose Herrera
Maria Jose Herrera
July 26, 2024
Level Up Your ColdFusion Skills with our Virtual Live Training: ColdBox from Zero to Hero

Level Up Your ColdFusion Skills with our Virtual Live Training: ColdBox from Zero to Hero

Level Up Your ColdFusion Skills with our Virtual Live Training: ColdBox from Zero to Hero

Are you a CFML developer looking to take your skills to the next level? Look no further than the ColdBox from Zero to Hero Virtual Live Training! This intensive two-day course will equip you with the knowledge and expertise to build robust and scalable applications using ColdBox 7, the latest version of the most popular CFML MVC framework.

What You'll Learn:

  • Master the Fun...

Cristobal Escobar
Cristobal Escobar
July 24, 2024