Skip to content

Disable anti-forgery checkλ︎

The ring-defaults library provides sensible Ring middleware defaults, especially in terms of security. The ring-defaults library is included in the

Anyone can send a GET request to a ring webapp, however with ring-defaults included then only pages / URLs from the webapp itself are allowed to POST.

Ring uses an anti-forgery token that needs to be setup in the project, otherwise you get the dreaded "Invalid Anti-forgery token" error message.

To keep things simple we are going to turn off the anti-forgery settings provided by Ring-Defaults so we can make our POST without the CSRF protection.

Note:: Edit the definition of app in src/shorturl-service/handler.clj and replace site-defaults with a function to set :anti-forgery to false in site-defaults.λ︎

(def app
  (assoc-in site-defaults [:security :anti-forgery] false)))

Ring middleware defaultsλ︎

There are a number of ring middleware defaults that define some common middleware functions for your app.

For example, here is the site-defaults definition

(def site-defaults
  "A default configuration for a browser-accessible website, based on current
  best practice."
  {:params    {:urlencoded true
               :multipart  true
               :nested     true
               :keywordize true}
   :cookies   true
   :session   {:flash true
               :cookie-attrs {:http-only true}}
   :security  {:anti-forgery   true
               :xss-protection {:enable? true, :mode :block}
               :frame-options  :sameorigin
               :content-type-options :nosniff}
   :static    {:resources "public"}
   :responses {:not-modified-responses true
               :absolute-redirects     true
               :content-types          true
               :default-charset        "utf-8"}})

A rough guide to security middleware from ringλ︎

  • :anti-forgery - Set to true to add CSRF protection via the ring-anti-forgery library.
  • :content-type-options - Prevents attacks based around media-type confusion. See: wrap-content-type-options.
  • :frame-options - Prevents your site from being placed in frames or iframes. See: wrap-frame-options.
  • :hsts - If true, enable HTTP Strict Transport Security. See: wrap-hsts.
  • :ssl-redirect - If true, redirect all HTTP requests to the equivalent HTTPS URL. A map with an :ssl-port option may be set instead, if the HTTPS server is on a non-standard port. See: wrap-ssl-redirect.
  • :xss-protection - Enable the X-XSS-Protection header that tells supporting browsers to use heuristics to detect XSS attacks. See: wrap-xss-protection.

See more details of ring middleware defaults

Adding other functions as middlewareλ︎

ring just uses function composition for middleware you can simply wrap your own function calls around the call to wrap defaults, so long as those functions deal with request/response maps appropriately.

(def app
    (wrap-defaults app-routes site-defaults)
  arguments to my additional middleware))

Or use the threading macro

(def app
  (-> (wrap-defaults app-routes site-defaults)
      (friend-stuff arg arg)
      (other-middleware arg arg arg))