From 33c882acda487459d45df89949896bde180b96c3 Mon Sep 17 00:00:00 2001 From: Toby Crawley Date: Mon, 11 Apr 2022 08:35:21 -0400 Subject: [PATCH 1/6] Switch to ring-defaults This simplifies our configuration a bit, and adds the following headers for improved security: - X-Content-Type-Options: nosniff - X-XSS-Protection: 1; mode=block --- project.clj | 2 +- src/clojars/http_utils.clj | 3 --- src/clojars/web.clj | 28 +++++++++++++++------------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/project.clj b/project.clj index a32d0b1d..05b004df 100644 --- a/project.clj +++ b/project.clj @@ -49,7 +49,7 @@ [cheshire "5.10.1"] [clj-stacktrace "0.2.8"] [clj-time "0.15.2"] - [ring/ring-anti-forgery "1.3.0" + [ring/ring-defaults "0.3.3" :exclusions [commons-codec ;; newer version brought in by ring/ring-core crypto-random]] diff --git a/src/clojars/http_utils.clj b/src/clojars/http_utils.clj index c4cc9f9b..fec67899 100644 --- a/src/clojars/http_utils.clj +++ b/src/clojars/http_utils.clj @@ -11,9 +11,6 @@ response )))) -(defn wrap-x-frame-options [f] - (fn [req] (update-in (f req) [:headers] assoc "X-Frame-Options" "DENY"))) - (defn https-request? [req] (or (= (:scheme req) :https) (= (get-in req [:headers "x-forwarded-proto"]) "https"))) diff --git a/src/clojars/web.clj b/src/clojars/web.clj index fbeaf5d8..cf00e5ef 100644 --- a/src/clojars/web.clj +++ b/src/clojars/web.clj @@ -8,7 +8,7 @@ [clojars.friend.oauth.github :as github] [clojars.friend.oauth.gitlab :as gitlab] [clojars.friend.registration :as registration] - [clojars.http-utils :refer [wrap-x-frame-options wrap-secure-session]] + [clojars.http-utils :refer [wrap-secure-session]] [clojars.log :as log] [clojars.middleware :refer [wrap-ignore-trailing-slash]] [clojars.routes.api :as api] @@ -27,14 +27,10 @@ [clojure.java.io :as io] [compojure.core :refer [ANY context GET PUT routes]] [compojure.route :refer [not-found]] - [ring.middleware.anti-forgery :refer [wrap-anti-forgery]] [ring.middleware.content-type :refer [wrap-content-type]] + [ring.middleware.defaults :as ring-defaults] [ring.middleware.flash :refer [wrap-flash]] - [ring.middleware.keyword-params :refer [wrap-keyword-params]] - [ring.middleware.multipart-params :refer [wrap-multipart-params]] - [ring.middleware.not-modified :refer [wrap-not-modified]] - [ring.middleware.params :refer [wrap-params]] - [ring.middleware.resource :refer [wrap-resource]])) + [ring.middleware.not-modified :refer [wrap-not-modified]])) (defn try-parse-page "Will throw a targeted error if maybe-page doesn't parse as an integer." @@ -94,6 +90,15 @@ [:h1 "Page not found"] [:p "Thundering typhoons! I think we lost it. Sorry!"]])))))) +(def ^:private defaults-config + (-> ring-defaults/secure-site-defaults + ;; Be more strict than the default; we never want to be frame-embedded + (assoc-in [:security :frame-options] :deny) + ;; we handle this in nginx + (update :security dissoc :ssl-redirect) + ;; We have our own session impl in http-utils + (dissoc :session))) + (defn clojars-app [{:keys [db error-reporter @@ -133,14 +138,11 @@ (gitlab/workflow gitlab http-client db)]}) (wrap-exceptions error-reporter) (log/wrap-request-context) - (wrap-anti-forgery) - (wrap-x-frame-options) - (wrap-keyword-params) - (wrap-params) - (wrap-multipart-params) + ;; Use flash directly since we have custom session logic, so can't use + ;; ring-defaults' session support (wrap-flash) + (ring-defaults/wrap-defaults defaults-config) (wrap-secure-session) - (wrap-resource "public") (wrap-content-type) (wrap-not-modified) (wrap-ignore-trailing-slash))))) From 8c104068521fa64626a70f89331d879a3d2a4813 Mon Sep 17 00:00:00 2001 From: Toby Crawley Date: Mon, 11 Apr 2022 17:51:55 -0400 Subject: [PATCH 2/6] Remove typekit js & custom font This allows for a cleaner/safer Content-Security-Policy, since we won't need `unsafe-inline` settings. --- resources/public/stylesheets/screen.css | 2 +- src/clojars/web/common.clj | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/resources/public/stylesheets/screen.css b/resources/public/stylesheets/screen.css index c3fa81c2..ba74041d 100644 --- a/resources/public/stylesheets/screen.css +++ b/resources/public/stylesheets/screen.css @@ -1,5 +1,5 @@ body { - font-family: "museo-sans-rounded", Arial, "Liberation Sans", FreeSans, sans-serif; + font-family: Arial, "Liberation Sans", FreeSans, sans-serif; background: #e2e4e3; } diff --git a/src/clojars/web/common.clj b/src/clojars/web/common.clj index 0ba951df..94cf4a16 100644 --- a/src/clojars/web/common.clj +++ b/src/clojars/web/common.clj @@ -83,9 +83,6 @@ [:img {:src "/images/clojurists-together-logo.png" :alt "Clojurists Together Foundation" :height "40"}])]]]]] [:footer.row])) -(defn typekit-js [] - [:script "try{Typekit.load({async:true});}catch(e){}"]) - (defn html-doc [title ctx & body] (html5 {:lang "en"} [:head @@ -109,8 +106,6 @@ ;; (then the default colors were removed) ;; more info: http://getbootstrap.com/css/#grid ["reset.css" "vendor/bootstrap/bootstrap.css" "screen.css"]) - (include-js "https://use.typekit.net/zhw0tse.js") - (typekit-js) (raw (when-ie (include-js "/js/html5.js"))) (include-js "/js/jquery-3.6.0.min.js") (for [path (:extra-js ctx)] @@ -190,8 +185,6 @@ ;; (then the default colors were removed) ;; more info: http://getbootstrap.com/css/#grid ["reset.css" "vendor/bootstrap/bootstrap.css" "screen.css"]) - (include-js "https://use.typekit.net/zhw0tse.js") - (typekit-js) (raw (when-ie (include-js "/js/html5.js")))] [:body.container-fluid [:div.hero.row From 3d0f2fafe172f4e9d1ba5348be5adf95cc28f7be Mon Sep 17 00:00:00 2001 From: Toby Crawley Date: Mon, 11 Apr 2022 17:55:24 -0400 Subject: [PATCH 3/6] Move selectText out of an inline script This allows us to add a Content-Security-Policy that doesn't have to include 'unsafe-inline' in the future, resulting in better XSS protection. --- resources/public/js/selectText.js | 14 ++++++++++++++ src/clojars/web/common.clj | 1 + src/clojars/web/dashboard.clj | 8 +++----- src/clojars/web/helpers.clj | 19 +------------------ src/clojars/web/jar.clj | 17 ++++++----------- 5 files changed, 25 insertions(+), 34 deletions(-) create mode 100644 resources/public/js/selectText.js diff --git a/resources/public/js/selectText.js b/resources/public/js/selectText.js new file mode 100644 index 00000000..d530a7dd --- /dev/null +++ b/resources/public/js/selectText.js @@ -0,0 +1,14 @@ +const selectText = (event) => { + if (window.getSelection) { + if (window.getSelection().type != 'Range') { + const range = document.createRange(); + range.selectNodeContents(event.currentTarget); + window.getSelection().removeAllRanges(); + window.getSelection().addRange(range); + } + } +}; + +$(() => { + $('.select-text').on('click', selectText); +}); diff --git a/src/clojars/web/common.clj b/src/clojars/web/common.clj index 94cf4a16..970b960a 100644 --- a/src/clojars/web/common.clj +++ b/src/clojars/web/common.clj @@ -108,6 +108,7 @@ ["reset.css" "vendor/bootstrap/bootstrap.css" "screen.css"]) (raw (when-ie (include-js "/js/html5.js"))) (include-js "/js/jquery-3.6.0.min.js") + (include-js "/js/selectText.js") (for [path (:extra-js ctx)] (include-js path))] [:body.container-fluid diff --git a/src/clojars/web/dashboard.clj b/src/clojars/web/dashboard.clj index ebaf7dd7..8b0fd67a 100644 --- a/src/clojars/web/dashboard.clj +++ b/src/clojars/web/dashboard.clj @@ -5,7 +5,6 @@ [clojars.web.common :refer [audit-table html-doc html-doc-with-large-header jar-link group-link tag verified-group-badge verified-group-badge-small]] - [clojars.web.helpers :as helpers] [clojars.web.structured-data :as structured-data] [hiccup.element :refer [unordered-list link-to]])) @@ -49,11 +48,10 @@ structured-data/website structured-data/organisation [:article.row - (helpers/select-text-script) [:div.push-information.col-xs-12.col-sm-4 [:h3.push-header "Push with " (link-to "http://leiningen.org/" "Leiningen")] - [:div#leiningen.push-example {:onClick "selectText('leiningen');"} + [:div#leiningen.push-example.select-text [:pre.push-example-leiningen (tag "$") " lein deploy clojars\n"]]] [:div.push-information.col-xs-12.col-sm-4 @@ -62,13 +60,13 @@ " (using " (link-to "https://github.com/adzerk/bootlaces" "bootlaces") ")"] - [:div#boot.push-example {:onClick "selectText('boot');"} + [:div#boot.push-example.select-text [:pre.push-example-boot (tag "$") " boot build-jar push-snapshot\n" (tag "$") " boot build-jar push-release\n"]]] [:div.push-information.col-xs-12.col-sm-4 [:h3.push-header "Maven Repository (running a " [:a {:href "https://github.com/clojars/clojars-web/wiki/Mirrors"} "mirror"] "?)"] - [:div#maven.push-example {:onClick "selectText('maven');"} + [:div#maven.push-example.select-text [:pre (tag "\n") (tag " ") "clojars.org" (tag "\n") diff --git a/src/clojars/web/helpers.clj b/src/clojars/web/helpers.clj index 6c64f8bf..4599983a 100644 --- a/src/clojars/web/helpers.clj +++ b/src/clojars/web/helpers.clj @@ -1,7 +1,6 @@ (ns clojars.web.helpers (:require [clojure.java.io :as io] - [clojure.string :as str] - [clojars.web.safe-hiccup :as hiccup])) + [clojure.string :as str])) (defn public-resource-exists? "Takes a path and checks whether the resource exists under the public directory @@ -37,19 +36,3 @@ :srcset (->> (filter identity [(srcset-part base extension "2x") (srcset-part base extension "3x")]) (str/join ", "))}])) - -(defn select-text-script [] - (hiccup/raw "")) diff --git a/src/clojars/web/jar.clj b/src/clojars/web/jar.clj index 3ef678e8..331ad111 100644 --- a/src/clojars/web/jar.clj +++ b/src/clojars/web/jar.clj @@ -142,8 +142,7 @@ (defn leiningen-coordinates [jar] (list [:h2 "Leiningen/Boot"] - [:div#leiningen-coordinates.package-config-example - {:onClick "selectText('leiningen-coordinates');"} + [:div#leiningen-coordinates.package-config-example.select-text [:pre (tag "[") (jar-name jar) @@ -153,8 +152,7 @@ (defn clojure-cli-coordinates [{:keys [group_name jar_name version]}] (list [:h2 "Clojure CLI/deps.edn"] - [:div#deps-coordinates.package-config-example - {:onClick "selectText('deps-coordinates');"} + [:div#deps-coordinates.package-config-example.select-text [:pre (str group_name "/" jar_name) \space @@ -166,8 +164,7 @@ (defn gradle-coordinates [{:keys [group_name jar_name version]}] (list [:h2 "Gradle"] - [:div#gradle-coordinates.package-config-example - {:onClick "selectText('gradle-coordinates');"} + [:div#gradle-coordinates.package-config-example.select-text [:pre "implementation(" [:span.string \" group_name ":" jar_name ":" version \"] @@ -176,8 +173,7 @@ (defn maven-coordinates [{:keys [group_name jar_name version]}] (list [:h2 "Maven"] - [:div#maven-coordinates.package-config-example - {:onClick "selectText('maven-coordinates');"} + [:div#maven-coordinates.package-config-example.select-text [:pre (tag "\n") (tag " ") group_name (tag "\n") @@ -271,8 +267,8 @@ "Want to display the " (link-to (version-badge-url jar) "latest version") " of your project on GitHub? Use the markdown code below!"] - [:textarea#version-badge - {:readonly "readonly" :rows 6 :onClick "selectText('version-badge')"} + [:textarea#version-badge.select-text + {:readonly "readonly" :rows 6} (badge-markdown jar)])) (defn show-jar [db stats account @@ -296,7 +292,6 @@ :data2 (format "[%s \"%s\"]" (jar-name jar) version)} [:div.light-article.row (breadcrumbs jar) - (helpers/select-text-script) [:div#jar-title.col-xs-12.col-sm-9 [:div [:h1 (jar-link jar)] From ddfda583a57caec8b5007798deddd96db5113b52 Mon Sep 17 00:00:00 2001 From: Toby Crawley Date: Tue, 12 Apr 2022 08:43:15 -0400 Subject: [PATCH 4/6] Extract form-table to common ns This allows us to use it elsewhere. --- src/clojars/web/common.clj | 12 +++++++++++- src/clojars/web/safe_hiccup.clj | 17 +++++++++-------- src/clojars/web/token.clj | 34 +++++++++++++-------------------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/clojars/web/common.clj b/src/clojars/web/common.clj index 970b960a..a87ecb07 100644 --- a/src/clojars/web/common.clj +++ b/src/clojars/web/common.clj @@ -2,7 +2,7 @@ (:require [clojars.maven :as maven] [clojars.web.helpers :as helpers] - [clojars.web.safe-hiccup :refer [html5 raw]] + [clojars.web.safe-hiccup :refer [form-to html5 raw]] [clojars.web.structured-data :as structured-data] [clojars.db :as db] [clojure.edn :as edn] @@ -429,3 +429,13 @@ [:td (link-project audit)] [:td (linkify (:message audit))] [:td (:created audit)]])]]) + +(defn form-table + [method-action label-input-pairs extra-inputs] + (form-to + method-action + [:div.form-table + [:table.form-table + (for [[label input] label-input-pairs] + [:tr [:td label] [:td input]])] + extra-inputs])) diff --git a/src/clojars/web/safe_hiccup.clj b/src/clojars/web/safe_hiccup.clj index 636e3cec..0eba87e0 100644 --- a/src/clojars/web/safe_hiccup.clj +++ b/src/clojars/web/safe_hiccup.clj @@ -41,11 +41,12 @@ does some monkey patching to automatically escape strings." "Create a form that points to a particular method and route. e.g. (form-to [:put \"/post\"] ...)" - [[method action] & body] - `(if (contains? #{:head :get} ~method) - (form/form-to [~method ~action] ~@body) - (form/form-to [~method ~action] - (conj - (form/hidden-field "__anti-forgery-token" - *anti-forgery-token*) - ~@body)))) \ No newline at end of file + [method-action & body] + `(let [[method# action#] ~method-action] + (if (contains? #{:head :get} method#) + (form/form-to [method# action#] ~@body) + (form/form-to [method# action#] + (conj + (form/hidden-field "__anti-forgery-token" + *anti-forgery-token*) + ~@body))))) diff --git a/src/clojars/web/token.clj b/src/clojars/web/token.clj index 97c9cd95..6394fe24 100644 --- a/src/clojars/web/token.clj +++ b/src/clojars/web/token.clj @@ -1,6 +1,6 @@ (ns clojars.web.token (:require - [clojars.web.common :refer [flash format-timestamp html-doc error-list]] + [clojars.web.common :refer [flash format-timestamp form-table html-doc error-list]] [clojars.web.safe-hiccup :refer [form-to]] [clojars.auth :as auth] [hiccup.form :refer [check-box drop-down label text-field submit-button]] @@ -45,12 +45,6 @@ ["30 days" "720"] ["90 days" "2160"]]) -(defn- form-table - [label-input-pairs] - [:table.form-table - (for [[label input] label-input-pairs] - [:tr [:td label] [:td input]])]) - (defn show-tokens ([account tokens jars groups] (show-tokens account tokens jars groups nil)) @@ -77,21 +71,19 @@ [:h2 "Create Deploy Token"] [:p [:strong "Note:"] " the token value will only be shown once after it is created, so be sure to copy it."] - (form-to + (form-table [:post "/tokens/"] - [:div.form-table - (form-table - [[(label :name "Token name") - (text-field {:placeholder "Laptop deploy token" - :required true} - :name)] - [(label :scope "Token scope") - (drop-down :scope (scope-options jars groups))] - [(label :single_use "Single use?") - (check-box :single_use)] - [(label :expires_in "Expires in") - (drop-down :expires_in expiry-options)]]) - (submit-button "Create Token")])] + [[(label :name "Token name") + (text-field {:placeholder "Laptop deploy token" + :required true} + :name)] + [(label :scope "Token scope") + (drop-down :scope (scope-options jars groups))] + [(label :single_use "Single use?") + (check-box :single_use)] + [(label :expires_in "Expires in") + (drop-down :expires_in expiry-options)]] + (submit-button "Create Token"))] [:div.token-table.col-xs-12.col-sm-12 [:h2 "Existing Deploy Tokens"] [:div From 83eb805c93dc03e53dc8677c90af35366dd870f1 Mon Sep 17 00:00:00 2001 From: Toby Crawley Date: Tue, 12 Apr 2022 08:43:41 -0400 Subject: [PATCH 5/6] Eliminate inline CSS This uses form-table to get rid of the need for inline css for forms with checkboxes. Having no inline CSS means we don't need the 'unsafe-inline' CSP, reducing our XSS risk. --- src/clojars/web/group.clj | 28 ++++++++++++---------------- src/clojars/web/user.clj | 25 ++++++++++++------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/clojars/web/group.clj b/src/clojars/web/group.clj index aefd8950..fb3b11cb 100644 --- a/src/clojars/web/group.clj +++ b/src/clojars/web/group.clj @@ -2,7 +2,7 @@ (:require [clojars.auth :refer [authorized-admin? authorized-member?]] [clojars.db :refer [find-group-verification jars-by-groupname]] - [clojars.web.common :refer [audit-table html-doc jar-link user-link error-list verified-group-badge-small]] + [clojars.web.common :refer [audit-table form-table html-doc jar-link user-link error-list verified-group-badge-small]] [clojars.web.safe-hiccup :refer [form-to]] [clojars.web.structured-data :as structured-data] [hiccup.element :refer [unordered-list]] @@ -66,20 +66,16 @@ (when admin? [:div.add-member [:h2 "Add member to group"] - (form-to [:post (str "/groups/" groupname)] - [:div - [:label - "Username " - (text-field "username")]] - [:div {:class "checkbox"} - [:label - "Admin? " - [:input {:type "checkbox" - :name "admin" - :id "admin" - :value 1 - :style "width:auto;margin-right:5px" - :checked false}]]] - [:input.button {:type "submit" :value "Add Member"}])]) + (form-table + [:post (str "/groups/" groupname)] + [[[:label "Username "] + (text-field "username")] + [[:label "Admin? "] + [:input {:type "checkbox" + :name "admin" + :id "admin" + :value 1 + :checked false}]]] + [:input.button {:type "submit" :value "Add Member"}])]) (when show-membership-details? (audit-table db groupname {:group-name groupname}))]))) diff --git a/src/clojars/web/user.clj b/src/clojars/web/user.clj index 65dffdbb..c599b57e 100644 --- a/src/clojars/web/user.clj +++ b/src/clojars/web/user.clj @@ -13,7 +13,7 @@ update-user update-user-notifications]] [clojars.log :as log] - [clojars.web.common :refer [html-doc error-list jar-link + [clojars.web.common :refer [html-doc error-list form-table jar-link flash group-link verified-group-badge-small]] [clojars.web.safe-hiccup :refer [form-to]] [clojure.string :refer [blank?]] @@ -149,18 +149,17 @@ (flash flash-msg) [:h1 "Notification Preferences"] (error-list errors) - (form-to [:post "/notification-preferences"] - [:label {:for :send-deploy-emails - :style "display:inline;margin-right:5px"} - "Receive deploy notification emails?"] - [:input {:type :checkbox - :name :send-deploy-emails - :id :send-deploy-emails - :value 1 - :style "display: inline;width:auto;margin-right:5px" - :checked (:send_deploy_emails user)}] - [:p "If checked, you will receive an email notifying you of every deploy in any group you are a member of."] - (submit-button "Update"))])) + (form-table + [:post "/notification-preferences"] + [[[:label {:for :send-deploy-emails} + "Receive deploy notification emails?"] + [:input {:type :checkbox + :name :send-deploy-emails + :id :send-deploy-emails + :value 1 + :checked (:send_deploy_emails user)}]]] + (list [:p "If checked, you will receive an email notifying you of every deploy in any group you are a member of."] + (submit-button "Update")))])) (defn update-notifications [db account {:keys [send-deploy-emails] :as _params}] (log/with-context {:tag :update-notification-preferences From 0f5b7d3cc752bd9f4be4d550833523e248d9e7f7 Mon Sep 17 00:00:00 2001 From: Toby Crawley Date: Tue, 12 Apr 2022 08:46:17 -0400 Subject: [PATCH 6/6] Add additional security headers This adds Content-Security-Policy and Permissions-Policy headers to reduce XSS risk, and adds a Referrer-Policy header to satisfy security checking tools. --- src/clojars/http_utils.clj | 31 +++++++++++++++++++++++++++++-- src/clojars/web.clj | 3 ++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/clojars/http_utils.clj b/src/clojars/http_utils.clj index fec67899..450dd5ab 100644 --- a/src/clojars/http_utils.clj +++ b/src/clojars/http_utils.clj @@ -1,5 +1,6 @@ (ns clojars.http-utils (:require + [clojure.string :as str] [ring.middleware.session :refer [wrap-session]] [ring.middleware.session.memory :as mem])) @@ -8,8 +9,7 @@ (let [response (handler req)] (if (= 200 (:status response)) (update-in response [:headers] assoc "Access-Control-Allow-Origin" "*") - response - )))) + response)))) (defn https-request? [req] (or (= (:scheme req) :https) @@ -34,3 +34,30 @@ (if (https-request? req) (secure-session req) (regular-session req))))) + +(def ^:private content-security-policy + (str/join + ";" + ;; Load anything from the clojars domain + ["default-src 'self'" + ;; Load images from clojars domain along with dnsimple's logo + "img-src 'self' https://cdn.dnsimple.com"])) + +(def ^:private permissions-policy + ;; We need zero features + ;; Generated using https://www.permissionspolicy.com/ + "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()") + +(defn wrap-additional-security-headers [f] + (fn [req] + (-> (f req) + ;; Restrict content loading to help prevent xss + (assoc-in [:headers "Content-Security-Policy"] content-security-policy) + ;; Don't allow usage of any advanced js features + (assoc-in [:headers "Permissions-Policy"] permissions-policy) + ;; Clojars URLs don't have sensitive content, so we could get away with + ;; "unsafe-url" here. But that will give us a poorer score on + ;; https://securityheaders.com and lead to vulnerability reports from + ;; folks using automated tools, so we set this to just not share the + ;; referrer with non-secure sites. + (assoc-in [:headers "Referrer-Policy"] "no-referrer-when-downgrade")))) diff --git a/src/clojars/web.clj b/src/clojars/web.clj index cf00e5ef..6ef90f54 100644 --- a/src/clojars/web.clj +++ b/src/clojars/web.clj @@ -8,7 +8,7 @@ [clojars.friend.oauth.github :as github] [clojars.friend.oauth.gitlab :as gitlab] [clojars.friend.registration :as registration] - [clojars.http-utils :refer [wrap-secure-session]] + [clojars.http-utils :refer [wrap-secure-session wrap-additional-security-headers]] [clojars.log :as log] [clojars.middleware :refer [wrap-ignore-trailing-slash]] [clojars.routes.api :as api] @@ -142,6 +142,7 @@ ;; ring-defaults' session support (wrap-flash) (ring-defaults/wrap-defaults defaults-config) + (wrap-additional-security-headers) (wrap-secure-session) (wrap-content-type) (wrap-not-modified)