Common Lisp允许在运行时执行/编译代码。但我想一些(类似脚本)的目的,如果不允许用户脚本调用某些函数(特别是对于应用程序扩展),那将是一件好事。人们仍然可以询问用户是否允许扩展访问文件/ ...我正在考虑使用Common Lisp的Android权限系统。如果不重写评估代码,这可能吗?
我看到的问题是,在Common Lisp中,您可能希望脚本能够使用读取器宏和普通宏以及后者运算符,如intern
,但这些将允许您获取任意符号(通过字符串)操纵和实习),因此在评估之前简单地扫描代码不足以确保不调用特定的功能。
那么,有没有类似功能的锁?我想过使用fmakunbound
/ makunbound
(并将值保存在局部变量中),但是在多线程环境中这是可能的吗?
提前致谢。
答案 0 :(得分:2)
这不是Common Lisp规范的一部分,并且没有扩展的Common Lisp实现使这种限制变得容易。
在我看来,使用操作系统限制(例如rlimit,功能等)来更容易在Common Lisp进程上强制执行您想要的操作。
答案 1 :(得分:1)
这不是一个不寻常的愿望,即在沙盒中运行不受信任的第三方代码。
您可以通过为脚本语言创建自定义解析器和解释器来手工制作沙箱。它是迂腐的,但却是正确的,因为任何带有API的程序都提供这样的服务。 API设计者和实现者需要担心恶劣的用户。
您仍然可以调用eval或编译器来运行沙盒脚本。它只是意味着您需要确保您的读者,解析器和语言拒绝提供对任何风险功能的访问。
您可以使用lisp包创建一个好的沙箱。您仍然可以将s表达式用于脚本语言的语法,但是您必须使标准阅读器瘫痪,以便用户无法转义package-sandbox。您仍然可以使用评估程序和编译器,但是您需要确保用户装入的程序包不包含任何可用于执行不适当操作的功能。
当您从空沙箱开始并慢慢添加功能时,成功的沙箱设计和构造会更容易。 Common Lisp是一种很大的语言,它为攻击者创造了巨大的表面。因此,如果您从包中创建一个沙箱,最好从一个空包开始,一次添加一个函数。思考他们创造的风险。创建残缺读者时,同样的方法也很好。不要从完整的读者开始,扔掉东西,从一个无用的读者开始并添加东西。遗憾的是,采用这种建议会给入门带来相当大的成本。但是,如果你环顾四周我怀疑你可以找到一个现有的安全读卡器。
Xach的建议是另一种方式,在许多情况下更直接。