在阅读了这个问题Security implications of Clojure keyword creation from user data?,特别是this answer后,我试图找到一个可以在REPL中演示该问题的案例。 这是一次尝试:
user> *clojure-version*
{:major 1, :minor 8, :incremental 0, :qualifier nil}
user> (def a (atom 0))
#'user/a
user> (defn bad-fn []
(println "called ")
(swap! a inc))
#'user/bad-fn
user> @a
0
user> (keyword "#=(bad-fn)")
:#=(bad-fn)
user> @a
0
如何重现此问题?
答案 0 :(得分:6)
问题不在于在字符串上调用keyword
会立即执行字符串中嵌入的任何代码,但如果您想将(keyword "foo #=(println :bar)")
的字符串表示存储在文件中,然后使用read
使用该文件,您最终会执行嵌入式代码。
当然,根本不建议使用read
用户提供的字符串,但这个问题是关于安全性的,所以答案(Brian和我的)描述了可能导致的安全问题从滥用各种设施以及具体命名的keyword
功能开始。
使用clojure.edn
(在2010年发布该问题时不可用)可以缓解#=
问题,但不能解决人们不应该期望能够读回{{1}字符串表示的更广泛问题1}}作为相同的关键字,无论哪个读者使用。如果不考虑这一点,很容易导致数据损坏。