分享您的想法,请访问2024 年 Clojure 状况调查!

欢迎!请参阅关于页面了解有关此信息的更多内容。

+1
语法和阅读器

我是 Clojure 新手,正在尝试理解语言的某些安全方面。

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

但我在 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

如果他们可以“不小心”包含一个额外的库并调用任意代码,那么他们可以意外地做任何事情。

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

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

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

我建议添加适当的文档,因为这里并不明确,可能会在未考虑到的位置创建代码执行。
来自
在这里,对 clojure.core/read 和 clojure.core/read-string 文本的描述能否澄清任何问题?这是多年以前在 Clojure 添加 clojure.edn 命名空间时编写的,并带上了 read 函数的 doesn't-read-code-only-data 变体,在我看来仍然准确:https://docs.clojure.org/clojure.core/read
来自
这里的困惑是否源于这个文档没有明确说明它所讨论的 *read-eval* 是哪个?

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

我明白有些人阅读了核心 read/read-string 文档后,接着阅读 tools.reader 的 read/read-string 文档,而没有意识到它所讨论的是一个独立的 clojure.tools.reader/*read-eval*,而不是核心变量。

我也可以理解为什么绑定核心变量的人想要它“通用地”应用(即,这也可能控制 Contrib 库的行为—假设 Contrib 库隶属于 Clojure org,因此可能存在某种依存关系)。
来自
Sean,我想这正好是我思考和困惑的地方。

我看到很多Clojure开发者使用了read-string,但并没有真正理解它对安全性的影响,甚至在尝试使用*read-eval*符号禁用它时也会变得混乱。在这个讨论中,我了解到需要将不同命名空间下的两个绑定区别开来。

我希望有一个绑定投入其中,能够确保在那些常见的read-string函数中不会有eval执行。
by
一个好的方法是教育开发者关于clojure.core/read和clojure.core/read-string的不安全性,例如,指向我给出的链接中的示例。

另一个方法是提供他们可以信任的几个安全函数,并建议他们使用这些函数。注释它们或撰写长长的文档字符串,随心所欲地解释它们为什么会更安全,以及替代方案中的不安全因素。

现成的替代品是为了那些使他们的代码更安全的用户的方便。然而,教育仍然是必需的,以便他们意识到这些函数的存在。
by
...并建议他们避免使用tools.reader函数——这是一个常见的传递依赖项,因此我可以看到他们如何在代码库中发现它,并认为使用“reader”命名空间读取字符串会是明显且正确的方式来做的。
...