From bc9f0fd529f7ce548263958df4447836f9bef90d Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Thu, 13 Apr 2017 13:50:36 -0700 Subject: [PATCH] Escape strings we're injecting in the index.html script to prevent XSS. --- resources/frontend_client/index_template.html | 1 - src/metabase/routes.clj | 12 +++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/resources/frontend_client/index_template.html b/resources/frontend_client/index_template.html index 9fd59f72037c8..c2c0924cc3dda 100644 --- a/resources/frontend_client/index_template.html +++ b/resources/frontend_client/index_template.html @@ -20,7 +20,6 @@ var configuredRoot = {{{base_href}}}; var actualRoot = "/"; - // THIS IS PROBABLY VULNERABLE TO XSS // Add trailing slashes var backendPathname = {{{uri}}}.replace(/\/*$/, "/"); // e.x. "/questions/" diff --git a/src/metabase/routes.clj b/src/metabase/routes.clj index 57a26577c7a37..e3dea9737fa4c 100644 --- a/src/metabase/routes.clj +++ b/src/metabase/routes.clj @@ -1,5 +1,6 @@ (ns metabase.routes (:require [clojure.java.io :as io] + [clojure.string :as str] [cheshire.core :as json] (compojure [core :refer [context defroutes GET]] [route :as route]) @@ -14,13 +15,18 @@ (defn- base-href [] (str (.getPath (clojure.java.io/as-url (public-settings/site-url))) "/")) +(defn- escape-script [str] + "Escapes ' tag" + ;; https://stackoverflow.com/questions/14780858/escape-in-script-tag-contents/23983448#23983448 + (str/replace str #" (if (init-status/complete?) (stencil/render-string (slurp (or (io/resource (str "frontend_client/" entry ".html")) (throw (Exception. (str "Cannot find './resources/frontend_client/" entry ".html'. Did you remember to build the Metabase frontend?"))))) - {:bootstrap_json (json/generate-string (public-settings/public-settings)) - :uri (json/generate-string uri) - :base_href (json/generate-string (base-href)) + {:bootstrap_json (escape-script (json/generate-string (public-settings/public-settings))) + :uri (escape-script (json/generate-string uri)) + :base_href (escape-script (json/generate-string (base-href))) :embed_code (when embeddable? (embed/head uri))}) (slurp (io/resource "frontend_client/init.html"))) resp/response