Skip to contents

api_csrf() installs CSRF middleware on a plumber2 API using the double-submit cookie pattern.

When installed:

  • Any form element inside template automatically includes a CSRF token.

  • If working in JavaScript contexts, the csrf_token() helper is also accessible inside templates.

Middleware behaviour:

  • On safe methods (GET, HEAD, OPTIONS), if the CSRF cookie is missing, a new token is generated and set as a cookie.

  • On unsafe methods (POST, PUT, DELETE, PATCH), the request is rejected with 403 Forbidden unless a token provided via the X-CSRF-Token header or a csrf_token field in the parsed request body matches the CSRF cookie.

This middleware installs freshwater request context.

Usage

api_csrf(api, secure = TRUE, exemptions = character())

Arguments

api

a plumber2 API object

secure

if TRUE, sets the CSRF cookie to "__Host-csrf" and marks the cookie as secure. If false, uses "csrf".

exemptions

character vector of route patterns to exempt from CSRF checks

Annotation Reference

CSRF exemptions can be specified by @csrf:

  • "on": (default) CSRF checks are enforced

  • "off" or "exempt": CSRF checks are skipped for the route

#* @post /foo/*/bar
#* @csrf exempt
function() {
 print("No checking!")
}

Background

Cross-site request forgery (CSRF) refers to attacks that trick user browsers into making unintended unsafe HTTP requests to trusted sites – often through piggybacking on existing authenticated user sessions.

In general, clients are most vulnerable when only cookies are used to validate requests from authenticated users. Read more: https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/CSRF

Examples

#* @plumber
function(api) {
  api |>
       api_csrf(secure = FALSE, exemptions = c("/foo/*", "/bar"))
}
#> function (api) 
#> {
#>     api_csrf(api, secure = FALSE, exemptions = c("/foo/*", "/bar"))
#> }
#> <environment: 0x5626a0342860>