all user inputs escaped
This commit is contained in:
@@ -4,33 +4,36 @@
|
|||||||
[NoteHub.views.css-generator]
|
[NoteHub.views.css-generator]
|
||||||
[noir.core :only [defpartial]]
|
[noir.core :only [defpartial]]
|
||||||
[noir.options :only [dev-mode?]]
|
[noir.options :only [dev-mode?]]
|
||||||
|
[hiccup.util :only [escape-html]]
|
||||||
[hiccup.page :only [include-js html5]]
|
[hiccup.page :only [include-js html5]]
|
||||||
[hiccup.element :only [javascript-tag]]))
|
[hiccup.element :only [javascript-tag]]))
|
||||||
|
|
||||||
; Creates the main html layout
|
; Creates the main html layout
|
||||||
(defpartial generate-layout
|
(defpartial generate-layout
|
||||||
[params title & content]
|
[params title & content]
|
||||||
(html5
|
; for the sake of security: escape all symbols of the param values
|
||||||
[:head
|
(let [params (into {} (for [[k v] params] [k (escape-html v)]))]
|
||||||
[:title (print-str (get-message :name) "—" title)]
|
(html5
|
||||||
[:link {:href
|
[:head
|
||||||
(clojure.string/replace
|
[:title (print-str (get-message :name) "—" title)]
|
||||||
(str "http://fonts.googleapis.com/css?family="
|
[:link {:href
|
||||||
(apply str
|
(clojure.string/replace
|
||||||
(interpose "|" (concat ["PT+Serif:700" "Noticia+Text:700"]
|
(str "http://fonts.googleapis.com/css?family="
|
||||||
(vals (select-keys params
|
(apply str
|
||||||
[:header-font :text-font])))))
|
(interpose "|" (concat ["PT+Serif:700" "Noticia+Text:700"]
|
||||||
"&subset=latin,cyrillic") " " "+")
|
(vals (select-keys params
|
||||||
:rel "stylesheet"
|
[:header-font :text-font])))))
|
||||||
:type "text/css"}]
|
"&subset=latin,cyrillic") " " "+")
|
||||||
[:style {:type "text/css"} (global-css params)]
|
:rel "stylesheet"
|
||||||
(if-not dev-mode? (include-js "/js/google-analytics.js"))]
|
:type "text/css"}]
|
||||||
(if (params :js)
|
[:style {:type "text/css"} (global-css params)]
|
||||||
[:body content
|
(if-not dev-mode? (include-js "/js/google-analytics.js"))]
|
||||||
(javascript-tag "var CLOSURE_NO_DEPS = true;")
|
(if (params :js)
|
||||||
(include-js "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js")
|
[:body content
|
||||||
(include-js "/cljs/main.js")]
|
(javascript-tag "var CLOSURE_NO_DEPS = true;")
|
||||||
[:body content])))
|
(include-js "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js")
|
||||||
|
(include-js "/cljs/main.js")]
|
||||||
|
[:body content]))))
|
||||||
|
|
||||||
(defn layout
|
(defn layout
|
||||||
"Generates the main html layout"
|
"Generates the main html layout"
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
[clojure.string :rename {replace sreplace} :only [split replace lower-case]]
|
[clojure.string :rename {replace sreplace} :only [split replace lower-case]]
|
||||||
[clojure.core.incubator :only [-?>]]
|
[clojure.core.incubator :only [-?>]]
|
||||||
[hiccup.form]
|
[hiccup.form]
|
||||||
[hiccup.page]
|
[hiccup.core]
|
||||||
|
[hiccup.util :only [escape-html]]
|
||||||
[noir.session :only [flash-put! flash-get]]
|
[noir.session :only [flash-put! flash-get]]
|
||||||
[noir.response :only [redirect status]]
|
[noir.response :only [redirect status]]
|
||||||
[noir.core :only [defpage render]]
|
[noir.core :only [defpage render]]
|
||||||
@@ -69,7 +70,7 @@
|
|||||||
[:table.central-element.helvetica-neue
|
[:table.central-element.helvetica-neue
|
||||||
[:tr
|
[:tr
|
||||||
(for [e [:column-why :column-how :column-geeks]]
|
(for [e [:column-why :column-how :column-geeks]]
|
||||||
(html5
|
(html
|
||||||
[:td.one-third-column
|
[:td.one-third-column
|
||||||
[:h2 (get-message e)] (md-to-html (get-message (keyword (str (name e) "-long"))))]))]]
|
[:h2 (get-message e)] (md-to-html (get-message (keyword (str (name e) "-long"))))]))]]
|
||||||
[:div.centered.helvetica-neue (md-to-html (get-message :created-by))]))
|
[:div.centered.helvetica-neue (md-to-html (get-message :created-by))]))
|
||||||
@@ -119,7 +120,7 @@
|
|||||||
; New Note Posting
|
; New Note Posting
|
||||||
(defpage [:post "/post-note"] {:keys [draft session-key session-value]}
|
(defpage [:post "/post-note"] {:keys [draft session-key session-value]}
|
||||||
(let [valid-session (flash-get session-key) ; it was posted from a newly generated form
|
(let [valid-session (flash-get session-key) ; it was posted from a newly generated form
|
||||||
valid-draft (not (empty? draft)) ; the note is non-empty
|
valid-draft (not (ccs/blank? draft)) ; the note has a meaningful content
|
||||||
valid-hash (try
|
valid-hash (try
|
||||||
(= (Short/parseShort session-value) ; the hash code is correct
|
(= (Short/parseShort session-value) ; the hash code is correct
|
||||||
(lib/hash #(.codePointAt % 0) (str draft session-key)))
|
(lib/hash #(.codePointAt % 0) (str draft session-key)))
|
||||||
@@ -128,6 +129,8 @@
|
|||||||
(if (and valid-session valid-draft valid-hash)
|
(if (and valid-session valid-draft valid-hash)
|
||||||
(let [[year month day] (map #(+ (second %) (.get (Calendar/getInstance) (first %)))
|
(let [[year month day] (map #(+ (second %) (.get (Calendar/getInstance) (first %)))
|
||||||
{Calendar/YEAR 0, Calendar/MONTH 1, Calendar/DAY_OF_MONTH 0})
|
{Calendar/YEAR 0, Calendar/MONTH 1, Calendar/DAY_OF_MONTH 0})
|
||||||
|
; This is the _only_ point where user's content enters the web app, so we escape the content.
|
||||||
|
draft (escape-html draft)
|
||||||
untrimmed-line (filter #(or (= \- %) (Character/isLetterOrDigit %))
|
untrimmed-line (filter #(or (= \- %) (Character/isLetterOrDigit %))
|
||||||
(-> draft ccs/split-lines first (sreplace " " "-") lower-case))
|
(-> draft ccs/split-lines first (sreplace " " "-") lower-case))
|
||||||
trim (fn [s] (apply str (drop-while #(= \- %) s)))
|
trim (fn [s] (apply str (drop-while #(= \- %) s)))
|
||||||
|
|||||||
Reference in New Issue
Block a user