Skip to content

Commit

Permalink
Prevent nil session from being overwritten
Browse files Browse the repository at this point in the history
Fixes #22.
  • Loading branch information
weavejester committed Jan 24, 2025
1 parent 45ff3f4 commit ddedc30
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 10 deletions.
25 changes: 15 additions & 10 deletions src/ring/middleware/anti_forgery/session.clj
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,30 @@
(defn- session-token [request]
(get-in request [:session :ring.middleware.anti-forgery/anti-forgery-token]))

(defn- nil-session? [response]
(and (contains? response :session) (nil? (:session response))))

(deftype SessionStrategy []
strategy/Strategy
(get-token [this request]
(get-token [_ request]
(or (session-token request)
(random-base64 60)))

(valid-token? [_ request token]
(when-let [stored-token (session-token request)]
(crypto/eq? token stored-token)))

(write-token [this request response token]
(let [old-token (session-token request)]
(if (= old-token token)
response
(-> response
(assoc :session (:session response (:session request)))
(assoc-in
[:session :ring.middleware.anti-forgery/anti-forgery-token]
token))))))
(write-token [_ request response token]
(if (nil-session? response)
response
(let [old-token (session-token request)]
(if (= old-token token)
response
(-> response
(assoc :session (:session response (:session request)))
(assoc-in
[:session :ring.middleware.anti-forgery/anti-forgery-token]
token)))))))

(defn session-strategy
"Implements a synchronizer token pattern strategy, suitable for passing to
Expand Down
7 changes: 7 additions & 0 deletions test/ring/middleware/test/anti_forgery.clj
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@
(is (contains? session ::af/anti-forgery-token))
(is (= (session "foo") "bar"))))

(deftest nil-session-response-test
(let [response {:status 200 :headers {} :session nil :body nil}
handler (wrap-anti-forgery (constantly response))
response' (handler (mock/request :get "/"))]
(is (contains? response' :session))
(is (nil? (:session response')))))

(deftest custom-error-response-test
(let [response {:status 200, :headers {}, :body "Foo"}
error-resp {:status 500, :headers {}, :body "Bar"}
Expand Down

0 comments on commit ddedc30

Please sign in to comment.