【发布时间】:2014-12-30 06:09:47
【问题描述】:
假设我想利用 Common Lisp 读取和执行 Common Lisp 代码的能力,以便我的程序可以执行用 Lisp 编写的外部代码,但我不信任该代码,因此我不希望它具有访问权限Common Lisp 的全部功能。我是否可以限制它的环境,使其只能看到我明确授予它访问权限的包/符号,从而有效地创建 DSL?
【问题讨论】:
标签: common-lisp dsl
假设我想利用 Common Lisp 读取和执行 Common Lisp 代码的能力,以便我的程序可以执行用 Lisp 编写的外部代码,但我不信任该代码,因此我不希望它具有访问权限Common Lisp 的全部功能。我是否可以限制它的环境,使其只能看到我明确授予它访问权限的包/符号,从而有效地创建 DSL?
【问题讨论】:
标签: common-lisp dsl
要阅读代码,首先禁用 *read-eval*(这会阻止人们在解析期间注入执行,使用类似 #.(do-evil-stuff) 的东西。您可能希望使用禁用大多数(如果不是全部)的自定义读取表进行读取) 读取宏。您可能希望使用自定义的一次性包进行读取,只导入您允许的符号。
阅读用户提供的代码后,您仍然需要验证代码中没有意外的函数/宏引用。如果您使用了自定义包,您应该能够确认每个符号属于“属于自定义一次性包”(这是用户提供的东西)或“从其他地方明确允许”(您将需要此列表来构建自定义包)。
完成后,您可以对其进行评估。
但是,正确执行此操作需要相当小心,您确实应该让其他人查看代码并积极尝试突破沙箱。
【讨论】:
查看chapter 4 of Let over lambda 中的“阅读器安全”部分,该部分深入讨论了该主题。特别是,您可能希望将*read-eval* 设置为nil。为了解决您关于限制对环境的访问的问题,这在 Common Lisp 中通常是困难的,因为它首先被设计为允许访问系统的大多数部分。也许您可以在白名单符号的方向上使用 Let over lambda 的思想(与链接章节中的宏字符黑名单相比)。我认为没有现成的解决方案。
【讨论】: