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* 绑定一样。

是的,在安全方面,我想确保开发者意识到他们想要执行权限。我建议将其默认设置为 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 组织,因此可能有一定的相互依赖性)。
作者:
Sean,我认为这正是我的想法和困惑所在。

我看到很多Clojure开发者在使用read-string时并没有真正理解其对安全性的影响。即使在尝试通过*read-eval*符号禁用它时,也会变得混淆不清。我在这次讨论中学到的是,需要将不同命名空间下的两个绑定放在同一个地方。

我希望有一个绑定,其中可以放置我可以确信不会有eval的常见read-string函数。
by
一个不错的做法是教育开发者关于clojure.core/read和clojure.core/read-string的不安全性,比如将他们指向我上面给出的链接中的例子。

另一个方法是提供一些你认为安全的函数,并建议他们使用这些函数。你可以对它们进行注释或者写很长的文档字符串来说明为什么它们更安全,以及为什么替代方案不安全。

现成的替代方案使用是为了方便让代码更安全的人。但仍然需要教育来让他们知道这些函数的存在。
by
...并阻止他们使用tools.reader函数——它是一个常见的传递依赖,我可以理解他们在代码库中是如何看到它的,并且认为使用“reader”命名空间来读取字符串是显然正确的方式。
...