we noticed this possibility of edn injection when mixing validated and
unvalidated data into a single edn blob. it's hard to exploit, and in
some sense it's obvious but i thought i'd share it since it caught us
off-guard and requires greater care than when serializing w/ json for
example.
Given a ring/compojure handler that mixes trusted/untrusted data into a map:
(GET "/submit-op" []
(fn [req]
(let [;; BAD: Mix unvalidated user input w/ trusted data (is-admin)
request-info {:raw-user-input (keyword (-> req :query-params (get "operation")))
:is-admin? false}
;; Serialize it for a backend worker/task queue.
serialized (pr-str request-info)
;; Just roundtrip it here for demonstration and print contents.
roundtripped (edn/read-string serialized)]
(for [[k v] roundtripped]
(lg/info "KEY[" k "]="v)))))
and the following request:
/submit-op?operation=register%20:is-admin?%20true}
the trusted data is overwritten
INFO 20140711 120431,062 rfz.web.routing ] KEY[ :raw-user-input ]= :register
INFO 20140711 120431,063 rfz.web.routing ] KEY[ :is-admin? ]= true
if i missed something about this, i apologize. in any case, take care,
validate data (as always) and don't mix trusted and untrusted data in
a call to pr-str.
ignacio