Skip to content

janetacarr/ring-anti-forgery

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ring-Anti-Forgery

Build Status

Ring middleware that prevents CSRF attacks. By default this uses the synchronizer token pattern.

Install

Add the following dependency to your project.clj:

[ring/ring-anti-forgery "1.3.0"]

Usage

The wrap-anti-forgery middleware function should be applied to your Ring handler.

Once applied, any request that isn't a HEAD or GET request will now require an anti-forgery token, or a 403 "access denied" response will be returned.

By default, the request is validated via the synchronizer token pattern, which requires the session middleware to be in place:

(require '[ring.middleware.anti-forgery :refer :all]
         '[ring.middleware.session :refer :all])

(def app
  (-> handler
      wrap-anti-forgery
      wrap-session))

The token will be used to validate the request is accessible via the *anti-forgery-token* var. The token is also placed in the request under the :anti-forgery-token key.

Custom token reader

By default the middleware looks for the anti-forgery token in the __anti-forgery-token form parameter, which can be added to your forms as a hidden field. For convenience, this library provides a function to generate the HTML of that hidden field:

(use 'ring.util.anti-forgery)

(anti-forgery-field)  ;; returns the HTML for the anti-forgery field

The middleware also looks for the token in the X-CSRF-Token and X-XSRF-Token header fields, which are commonly used in AJAX requests.

This behavior can be customized further by supplying a function to the :read-token option. This function is passed the request map, and should return the anti-forgery token found in the request.

(defn get-custom-token [request]
  (get-in request [:headers "x-forgery-token"]))

(def app
  (-> handler
      (wrap-anti-forgery {:read-token get-custom-token})
      (wrap-session)))

Custom error handling

It's also possible to customize the error response returned when the token is invalid or missing:

(def custom-error-response
  {:status 403
   :headers {"Content-Type" "text/html"}
   :body "<h1>Missing anti-forgery token</h1>"})

(def app
  (-> handler
      (wrap-anti-forgery {:error-response custom-error-response})
      (wrap-session)))

Or, for more control, an error handler can be supplied:

(defn custom-error-handler [request]
  {:status 403
   :headers {"Content-Type" "text/html"}
   :body "<h1>Missing anti-forgery token</h1>"})

(def app
  (-> handler
      (wrap-anti-forgery {:error-handler custom-error-handler})
      (wrap-session)))

Custom token strategy

The synchronizer pattern is not the only way of preventing CSRF attacks. There a number of different strategies, and the middleware in this library can support them through the :strategy option:

(def app
  (wrap-anti-forgery handler {:strategy custom-strategy}))

The custom strategy must satisfy the Strategy protocol. Some third-party strategies already exist:

Further Documentation

Caveats

This middleware will prevent all HTTP methods except for GET and HEAD from accessing your handler without a valid anti-forgery token.

You should therefore only apply this middleware to the parts of your application designed to be accessed through a web browser. This middleware should not be applied to handlers that define web services.

License

Copyright © 2018 James Reeves

Distributed under the MIT License, the same as Ring.

About

Ring middleware to prevent CSRF attacks

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Clojure 100.0%