请在的2024年Clojure调查中分享您的想法!

欢迎!有关该功能的更多信息,请参阅关于页面。

+1
语法和reader by

我是Clojure的新手,正在尝试理解该语言的一些安全问题。

在文档中,我了解到将read-eval绑定到未知应该拒绝执行代码。

但在我用clojure.core/read-string进行代码实验时,它通过使用clojure.tools.reader/read-string正常工作。

我还看到reader.edn不会执行代码,但我想确保即使我们的开发人员误用了clojure.tools.reader,也不会执行任何代码。

先行感谢,Rotem

POC

(binding [*read-eval* :unknown]
(clojure.tools.reader/read-string "#=(* 2 21)"))
=> 42

1 答案

+1
by

如果他们在“错误”中包含了一个额外的库并执行任意代码,那么他们可以错误地做任何事情。

clojure.tools.reader有一个类似的动态变量clojure.tools.reader/*read-eval*,也是以相同的方式使用的,所以您需要绑定两个。

by
明白了,我想要将一个 *read-eval* 设置为未知,以便于测试以验证没有代码正在运行,就像 clojure.core 不需要 clojure.core/*read-eval* 绑定一样。

是的,在安全性方面,我想确保开发者知道他们需要 eval 功能。我建议将其默认设置为 false,但这是一个更核心的要求。

我建议添加适当的文档,因为它并不清晰,并可能在我们没有考虑到的地方创建代码执行。
以下关于 clojure.core/read 和 clojure.core/read-string 的文本是否有所解释?这是在 clojure.edn 命名空间与 Clojure 结合、添加了只读取数据的 read 函数的变体时编写的,对我来说仍然看来是准确的:https://docs.clojure.org/clojure.core/read
这种混淆是否源于这份文档没有明确说明所讨论的 *read-eval* 是哪一个?

http://clojure.github.io/tools.reader/#clojure.tools.reader/read-string

我可以理解,为什么有人在阅读 core read/read-string 文档后,接着阅读 tools.reader 的文档(针对其自身的 read/read-string),而没有意识到它讨论的是单独的 clojure.tools.reader/*read-eval* 而不是核心变量。

我还可以理解,为什么那些绑定核心变量的人希望它“普遍”适用(也就是说,它也可能控制 Contrib 库的行为——基于假设 Contrib 库属于 Clojure 组织,因此它们可能会有一定的相互依赖性)。
Sean,我认为这正是我思想和困惑的地方。

我看到许多 Clojure 开发者使用 read-string,但并没有真正理解它对安全性的影响,甚至当试图使用 *read-eval* 符号禁用它时也会感到困惑,我在这次讨论中学到了需要放置不同命名空间的两个绑定。

我希望有一个可以绑定的变量,可以确保那些常见的 read-string 函数中不会有 eval。
by
一个很好的方法就是教育开发者关于 clojure.core/read 和 clojure.core/read-string 的不安全性,例如指向我上面给出的链接中的示例。

另一种方法是为他们提供几组他们信任是安全的函数,并建议他们使用这些。 给它们加上注释或写长长的文档字符串,说明为什么它们更安全,以及替代方案的不安全性在哪里。

现成的替代品是为了方便那些使自己的代码更安全的人。 但是仍需要教育,以便他们知道这些函数的存在。
by
...并鼓励他们不要使用 tools.reader 的函数 — 它是一个常见的传递依赖项,因此我可以看出他们如何在代码库中发现它,并认为使用“reader”命名空间来读取字符串是显然的、正确的方式。
...