Clojure关键字示例安全问题

时间:2017-01-18 10:20:02

标签: security clojure

在阅读了这个问题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

如何重现此问题?

1 个答案:

答案 0 :(得分:6)

问题不在于在字符串上调用keyword会立即执行字符串中嵌入的任何代码,但如果您想将(keyword "foo #=(println :bar)")的字符串表示存储在文件中,然后使用read使用该文件,您最终会执行嵌入式代码。

当然,根本不建议使用read用户提供的字符串,但这个问题是关于安全性的,所以答案(Brian和我的)描述了可能导致的安全问题从滥用各种设施以及具体命名的keyword功能开始。

使用clojure.edn(在2010年发布该问题时不可用)可以缓解#=问题,但不能解决人们不应该期望能够读回{{1}字符串表示的更广泛问题1}}作为相同的关键字,无论哪个读者使用。如果不考虑这一点,很容易导致数据损坏。