请让计算机安全人员可以分析/审核您的语言。
安全人员需要能够在程序发布之前找到程序中的漏洞。理想情况下,我们会在早期被调用,并且可以在代码库开发时对其进行评论,但通常不会。
当出现新版本的语言或核心库时,以前安全的事情可能不再是:
- 库可能会变得更强大:例如,URL库现在支持
javascript:
- 可能会有新的方式将字符串或字节转换为代码:例如,
eval
或反序列化库
- 语言反射技术可能会变得更加强大:例如,暴露局部变量
这些更改中的任何一项都可以增加程序具有的可滥用权限,但是由于程序使用的权限(当与非恶意客户端打交道时)没有更改,因此安全人员很难在不进行大量操作的情况下就找出来。重新审核。
因此,在设计和版本化语言时,请考虑我们。以下是一些提示:
定义一些可以分解为程序的原语。
这样HTML5尤其糟糕。他们显然把很多心思的安全,并有一些非常聪明的人,但不是指定新节目元素,如<video>
在旧的条款,或创建一个共同的抽象,新<video>
老<img>
两可的条款规定,<video>
又是另一个一次性程序元素,其自身会带来安全后果。
使您的语言适合静态分析(即使不是静态类型的)。
安全人员经常使用静态分析来查找模式,并尝试排除程序的某些部分,以便他们可以专注于真正棘手的部分。
显而易见,哪些标识符是局部变量,哪些不是。
例如,不要与旧版本的JavaScript犯同样的错误,这使得在下面的代码中无法分辨是否x
是局部变量引用(根据规范的旧版本的字面意思):
if (Math.random() > 0.5) {
Object.prototype.x = 0;
}
function f() {
var x = 1;
(function () {
alert(x); // Might alert 0, might alert 1.
})();
}
允许可分解的安全性
许多安全系统是围绕安全内核设计的,该内核保留了安全属性,因此安全人员可以集中精力分析少量代码,并使大多数程序员不必面对烦人,烦躁,偏执,偏执的安全人员。 。
应该可以使用您的语言编写这样的内核。如果您的语言的安全性之一是是否仅会提取URL的特定子集,内核编写者是否可以做一些事情来引导所有URL提取通过他们的代码?或者,静态构建检查(例如查看导入)可以起到相同的作用。
有些语言(例如Newspeak)使用对象功能模型。这是获得可分解安全性的绝佳方法。
但是,如果您不能做到这一点,那么使模块图成为可静态分析的工件可以为您带来很多好处。如果我可以证明某个模块无法到达文件I / O模块(通过在TCB中调用模块中的代码除外),则可以从该模块中排除所有类的问题。
限制嵌入式脚本语言的权限
许多有用的系统被组织为一个静态核心,它启动了许多用动态(甚至功能)语言编写的代码。
嵌入脚本语言可以使系统更具扩展性。
但是脚本语言不应具有VM的全部权限。
如果您选择允许嵌入式脚本语言,请使调用者可以轻松地限制其功能。一个对象能力模型(请参见上面对Newspeak的评论)在这里非常合适;因此,在使用脚本语言评估代码时,调用者应传入要执行的代码以及该代码的所有全局变量。
治疗eval
作为一种语言本身嵌入的脚本语言
如果您的语言可以调用自己的编译器将字符串转换为代码,则可以像使用任何嵌入式脚本语言一样,对其进行沙盒处理。
使用简单的并发模型
我们的安全人员在试图弄清楚是否维护安全资产时,不希望担心种族状况。
在建立线程之前,请考虑使用线程替代方法作为几乎无法保护的默认选项。
一个简单的例子就是事件循环并发,就像在E,Verilog和JavaScript中发现的那样。
不要鼓励引述混乱
有些语言是粘合语言,最终它们会处理许多不同语言的字符串。
例如,JavaScript通常包含HTML,CSS,XML,JSON甚至JavaScript的字符串。程序员很难记住在将纯文本字符串组合成其他语言的字符串时正确地编码它们,因此,毫无疑问,JS程序会遇到各种引语混乱的问题:XSS最糟糕。
如果要包括字符串组成功能,请尝试减少程序员的安全负担。DSL,卫生宏和嵌入式模板语言可以通过将负担适当地转移到图书馆或语言开发人员身上,并远离最终开发人员来实现此目的。