Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for origin/referrer checking #338

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example-project/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
[lein-ancient "0.6.15"]
[com.cemerick/austin "0.1.6"]
[lein-cljsbuild "1.1.7"]
[cider/cider-nrepl "0.19.0"]] ; Optional, for use with Emacs
[cider/cider-nrepl "0.21.0"]] ; Optional, for use with Emacs

:cljsbuild
{:builds
Expand Down
8 changes: 6 additions & 2 deletions example-project/src/example/server.clj
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@
(defn landing-pg-handler [ring-req]
(hiccup/html
[:h1 "Sente reference example"]
[:div#sente-csrf-token {:data-csrf-token anti-forgery/*anti-forgery-token*}]
(let [csrf-token
;; (:anti-forgery-token ring-req) ; Also an option
(force anti-forgery/*anti-forgery-token*)]

[:div#sente-csrf-token {:data-csrf-token csrf-token}])
[:p "An Ajax/WebSocket" [:strong " (random choice!)"] " has been configured for this example"]
[:hr]
[:p [:strong "Step 1: "] " try hitting the buttons:"]
Expand Down Expand Up @@ -181,7 +185,7 @@
uid (:uid session)]
(debugf "Unhandled event: %s" event)
(when ?reply-fn
(?reply-fn {:umatched-event-as-echoed-from-from-server event}))))
(?reply-fn {:umatched-event-as-echoed-from-server event}))))

(defmethod -event-msg-handler :example/test-rapid-push
[ev-msg] (test-fast-server>user-pushes))
Expand Down
32 changes: 31 additions & 1 deletion src/taoensso/sente.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,28 @@
^:private send-buffered-server-evs>ajax-clients!
^:private default-client-side-ajax-timeout-ms)

(defn- bad-origin?
[allowed-origins {:keys [headers]}]
(let [origin (get headers "origin")
referer (get headers "referer" "")]
(cond (= allowed-origins :all) false
(contains? (set allowed-origins) origin) false
(some #(str/starts-with? referer (str % "/")) allowed-origins) false
:else true)))

(comment
;; good
(bad-origin? :all {:headers {"origin" "http://site.com"}})
(bad-origin? #{"http://site.com"} {:headers {"origin" "http://site.com"}})
(bad-origin? #{"http://site.com"} {:headers {"referer" "http://site.com/"}})

;; bad
(bad-origin? #{"http://site.com"} {:headers nil})
(bad-origin? #{"http://site.com"} {:headers {"origin" "http://attacker.com"}})
(bad-origin? #{"http://site.com"} {:headers {"referer" "http://attacker.com/"}})
(bad-origin? #{"http://site.com"} {:headers {"referer" "http://site.com.attacker.com/"}})
)

(defn make-channel-socket-server!
"Takes a web server adapter[1] and returns a map with keys:
:ch-recv ; core.async channel to receive `event-msg`s (internal or from clients).
Expand Down Expand Up @@ -299,14 +321,16 @@
[web-server-ch-adapter
& [{:keys [recv-buf-or-n ws-kalive-ms lp-timeout-ms
send-buf-ms-ajax send-buf-ms-ws
user-id-fn bad-csrf-fn csrf-token-fn handshake-data-fn packer]
user-id-fn bad-csrf-fn bad-origin-fn csrf-token-fn handshake-data-fn packer allowed-origins]
:or {recv-buf-or-n (async/sliding-buffer 1000)
ws-kalive-ms (enc/ms :secs 25) ; < Heroku 55s timeout
lp-timeout-ms (enc/ms :secs 20) ; < Heroku 30s timeout
send-buf-ms-ajax 100
send-buf-ms-ws 30
user-id-fn (fn [ring-req] (get-in ring-req [:session :uid]))
bad-csrf-fn (fn [ring-req] {:status 403 :body "Bad CSRF token"})
allowed-origins :all
bad-origin-fn (fn [_] {:status 403 :body "Unauthorized origin"})
csrf-token-fn (fn [ring-req]
(or (:anti-forgery-token ring-req)
(get-in ring-req [:session :csrf-token])
Expand Down Expand Up @@ -526,6 +550,9 @@
(bad-csrf? ring-req)
(bad-csrf-fn ring-req)

(bad-origin? allowed-origins ring-req)
(bad-origin-fn ring-req)

:else
(interfaces/ring-req->server-ch-resp web-server-ch-adapter ring-req
{:on-open
Expand Down Expand Up @@ -602,6 +629,9 @@
(bad-csrf? ring-req)
(bad-csrf-fn ring-req)

(bad-origin? allowed-origins ring-req)
(bad-origin-fn ring-req)

:else
(interfaces/ring-req->server-ch-resp web-server-ch-adapter ring-req
{:on-open
Expand Down