保护 JavaScript 对象免受外部脚本的攻击
Protecting a JavaScript object against external scripts
Web 应用模型
假设我有一个敏感的 JS 对象,我可以通过它来做关键的事情。我的要求是我想完全包装这个对象,这样就没人可以访问它了。这是我包装这个对象的模式。
var proxy = (function (window){
// A private reference to my critical object (i.e. big apple)
var bigApple = window.bigApple;
// Delete this property so that no one else can access it
delete window.bigApple;
// Oooah, It's mine! I'm now eating it :)
// Public APIs exposed globally
return {
doStuffWithBigApple: function (){
// The Script element being executed now
var who = document.currentScript;
// Access control
if(isLegitimate(who)){
return bigApple.doStuff();
}
}
};
}) (window);
通过这段代码,我导出了一个名为 proxy
的 public 文字对象,以便每个人都可以访问它。
那是什么isLegitimate
?它是一个要实现的抽象函数,它决定哪些 script
元素访问我的大苹果的哪些方法。该决定是根据 script
元素的 src
属性做出的。 (即他们的域名)
其他人这样使用 public API:
proxy.doStuffWithBigApple();
攻击模型
在我的网络应用程序中有用于广告的占位符,这样可以加载和执行包括 JavaScript 代码在内的外部内容。所有这些外部资源都渴望访问我的大苹果。
注意:这些是在我的脚本之后添加的,导致无法访问原始window.bigApple
。
我的问题
我的安全模型有什么规避方法吗?
关键边缘:
- 在解析时更改
src
属性。 --- 不可能,因为src
只能设置一次。
- 在 运行 时添加
script
元素 --- 没有出现问题
我觉得你创建代理的想法很好,但是,如果你可以访问 ES6,为什么不研究一下 Proxy?我认为它可以开箱即用。
MDN 提供了很好的示例,说明如何在 setter 等中进行值验证陷阱
编辑:
可能的陷阱我想象过:
IE 不支持
document.currentScript
。因此,如果您关心它并决定对 it/use 预先存在的 polyfill 进行 polyfill,请确保它是安全的。或者它可以用于动态修改 document.currentScript
返回的外部脚本 url 并倾斜代理。我不知道这是否会发生在现实生活中。
这种保护JavaScript对象的方法有一个非常重要的问题需要解决,否则这种方法将无法正常工作。
MDN 在此 API 上指出:
It's important to note that this will not reference the <script>
element if the code in the script is being called as a callback or event handler; it will only reference the element while it's initially being processed.
因此,在回调和事件处理程序中对 proxy.doStuffWithBigApple();
的任何调用都可能导致您的框架行为异常。
Web 应用模型
假设我有一个敏感的 JS 对象,我可以通过它来做关键的事情。我的要求是我想完全包装这个对象,这样就没人可以访问它了。这是我包装这个对象的模式。
var proxy = (function (window){
// A private reference to my critical object (i.e. big apple)
var bigApple = window.bigApple;
// Delete this property so that no one else can access it
delete window.bigApple;
// Oooah, It's mine! I'm now eating it :)
// Public APIs exposed globally
return {
doStuffWithBigApple: function (){
// The Script element being executed now
var who = document.currentScript;
// Access control
if(isLegitimate(who)){
return bigApple.doStuff();
}
}
};
}) (window);
通过这段代码,我导出了一个名为 proxy
的 public 文字对象,以便每个人都可以访问它。
那是什么isLegitimate
?它是一个要实现的抽象函数,它决定哪些 script
元素访问我的大苹果的哪些方法。该决定是根据 script
元素的 src
属性做出的。 (即他们的域名)
其他人这样使用 public API:
proxy.doStuffWithBigApple();
攻击模型
在我的网络应用程序中有用于广告的占位符,这样可以加载和执行包括 JavaScript 代码在内的外部内容。所有这些外部资源都渴望访问我的大苹果。
注意:这些是在我的脚本之后添加的,导致无法访问原始window.bigApple
。
我的问题
我的安全模型有什么规避方法吗?
关键边缘:
- 在解析时更改
src
属性。 --- 不可能,因为src
只能设置一次。 - 在 运行 时添加
script
元素 --- 没有出现问题
我觉得你创建代理的想法很好,但是,如果你可以访问 ES6,为什么不研究一下 Proxy?我认为它可以开箱即用。
MDN 提供了很好的示例,说明如何在 setter 等中进行值验证陷阱
编辑:
可能的陷阱我想象过:
IE 不支持 document.currentScript
。因此,如果您关心它并决定对 it/use 预先存在的 polyfill 进行 polyfill,请确保它是安全的。或者它可以用于动态修改 document.currentScript
返回的外部脚本 url 并倾斜代理。我不知道这是否会发生在现实生活中。
这种保护JavaScript对象的方法有一个非常重要的问题需要解决,否则这种方法将无法正常工作。
MDN 在此 API 上指出:
It's important to note that this will not reference the
<script>
element if the code in the script is being called as a callback or event handler; it will only reference the element while it's initially being processed.
因此,在回调和事件处理程序中对 proxy.doStuffWithBigApple();
的任何调用都可能导致您的框架行为异常。