请在 2024 Clojure 状态调查! 中分享您的想法。

欢迎!请访问 关于 页面了解更多关于这个工作的信息。

+1 投票
语法和读取器

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

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

但是,我在 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 有一个相似的动态变量,clojure.tools.reader/*read-eval*,它以相同的方式使用,因此你需要绑定两个。

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

是的,在安全性方面,我想确保开发者意识到他们需要.eval功能。我建议默认设置为否,但这是一个更核心的要求。

建议添加适当的文档,因为这并不清楚,也可能在我们没有想到可能的地方创建代码执行。
这里关于 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" 命名空间读取字符串会是明显、正确的做法。
...