Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use ring anti-forgery / CSRF token with latest version ring/compojure?

I copied some old code that was working in compojure 1.1.18 and other old libs, but using the latest versions I can't get it to work.

Here's my minimal example code copied from the minimal example here to demonstrate that with latest ring and compojure libraries, I get an error when I send an http POST, even with the header set.

lein ring server to start it, then do

curl -X GET --cookie-jar cookies "http://localhost:3000/" which results in something like this:

{"csrf-token":"7JnNbzx8BNG/kAeH4bz1jDdGc7zPC4TddDyiyPGX3jmpVilhyXJ7AOjfJgeQllGthFeVS/rgG4GpkUaF"}

But when I do this

curl -X POST -v --cookie cookies -F "[email protected]" --header "X-CSRF-Token: 7JnNbzx8BNG/kAeH4bz1jDdGc7zPC4TddDyiyPGX3jmpVilhyXJ7AOjfJgeQllGthFeVS/rgG4GpkUaF" http://localhost:3000/send

I get <h1>Invalid anti-forgery token</h1>

Am I doing something wrong?

The code I borrowed was intended to answer this question.

like image 380
sventechie Avatar asked May 11 '15 16:05

sventechie


People also ask

Can I reuse CSRF token?

edited. We recently had a pentest running and one security flaw that was reported is that CSRF-Tokens can be reused over multiple requests.

How do anti forgery tokens work?

Anti-Forgery TokensOne token is sent as a cookie. The other is placed in a hidden form field. The tokens are generated randomly so that an adversary cannot guess the values. When the client submits the form, it must send both tokens back to the server.

Can you steal CSRF token?

Stealing Anti-CSRF Tokens: When CSRF tokens are passed as cookie parameters without Secure and HTTPOnly flags, an attacker can potentially steal the CSRF token via XSS or other attacks.

How is CSRF token validated?

CSRF tokens are unique and validated on GET/POST requests to ensure there is no cross site requests being made in Salesforce. Once a request is made, the auto generated token is validated to confirm if the request is from the UI and not an intiated request from another site.


1 Answers

The problem was that ring-defaults (which replaces the compojure.handler namespace in compojure >= 1.2) automatically uses ring anti-forgery in the usual mode of use:

(defroutes app-routes
  (GET "/" [] (generate-string {:csrf-token
                                *anti-forgery-token*}))
  (POST "/send" [email] "ok")
  (resources "/")
  (not-found "Not Found"))

(def app
  (-> app-routes
   (wrap-defaults site-defaults)))

So two anti-forgery tokens were being generated and the GET request provided the invalid one. Removing the wrap-anti-forgery line fixed the problem.

like image 158
sventechie Avatar answered Sep 22 '22 14:09

sventechie