假设我在其上接受用户提供的字符串,userstring和call(关键字userstring)。
这样做是否存在安全问题?如果是这样,那么减轻它们的最佳方法是什么?
答案 0 :(得分:7)
每http://clojure.org/reader,有符号和关键字中字符有效的规则。 (目前,字母数字字符和*
,+
,!
,-
,_
和?
。)您永远不应创建包含任何其他字符的符号。但是,目前,这些规则完全没有被编译器强制执行。
最多可能会出现无效的关键字。在最坏的情况下,你可能最终会遇到邪恶/危险的人
MichałMarczyk说。请记住,#=()
可用于在读取时运行任意代码,因此您甚至不必为不良事件评估字符串,您只需要阅读它。
(keyword "foo #=(steal-passwords-and-delete-hard-drive)")
(有关如何禁用此行为,请参阅(doc *read-eval*)
,但默认情况下启用了read-eval。)
我认为清理用户输入的一般规则适用于此处。准确定义您想要允许的内容,并默认禁止其他所有内容。也许允许像正则表达式#"[a-zA-Z0-9*+!-_?]+"
这样的东西,可能还有其他字母数字取决于你说的语言。
答案 1 :(得分:6)
脱离我的头顶:
(keyword s)
将创建名称为s
的非命名空间关键字,无论此关键字是否可由关键字字面值表示。如果您打算将这些关键字作为某些配置文件的一部分打印出来,那么这可能是一个安全问题,然后尝试将其用作可信代码:
(with-out-str (println (keyword "foo (println :bar)")))
; => :foo (println :bar)
此外,以下是来自Google网上论坛的两个主题(第一个来自clojure-dev):
Request for Improvement (with patch): non-interning keyword lookup
摘要:实习垃圾关键字可能是内存泄漏,因此您应该考虑对可能实习的字符串进行一些预处理,如果它们来自不受信任的来源。