Javascript 是否可能对返回JSON对象的URL执行跨站点请求伪造攻击?

Javascript 是否可能对返回JSON对象的URL执行跨站点请求伪造攻击?,javascript,json,xss,security,xmlhttprequest,Javascript,Json,Xss,Security,Xmlhttprequest,我知道有一种方法可以对通过重载数组构造函数返回数组的请求执行。例如,假设我有一个带有URL的站点: foo.com/getJson 这将返回: ['Puff the Dragon', 'Credit Card #'] 这通常是我自己的站点在XHR请求后使用的Javascripteval,但另一个站点可以通过包含以下内容来嗅探此数据: <script> function Array() { var arr = this; var i = 0; var next = f

我知道有一种方法可以对通过重载数组构造函数返回数组的请求执行。例如,假设我有一个带有URL的站点:

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>

我想不出一个办法,但也许我错过了什么。我知道有更好的解决方案来保护我的站点,比如在URL中使用或要求使用auth令牌,但我正在尝试找出是否存在这种安全漏洞。

我看到的源代码,例如和,明确指出根对象是安全的(可能在所有主要浏览器中)。这是因为脚本不能以对象文字开头。默认情况下,ASP.NET使用包装对象和数组,但我认为这只是为了简化客户端库。

从中可以看出,JSON对象不应被视为有效的Javascript程序:

“请注意,表达式声明 不能从开头的卷发开始 振作起来,因为那样可能会成功 用块表示不明确


因此,假设所有浏览器都正确实现了这一点,像
{name:'Puff the Dragon',cc:'Credit Card#'}
这样的响应将不会作为有效的Javascript执行。但是像
({name:'Puff the Dragon',cc:'Credit Card#'})和
{['Puff the Dragon',Credit Card#]]这样的表达式
将。

您可以对
对象使用相同的技术。它不会影响原型链,因此不会被所有对象继承。但是,例如,您可以使用以下方法记录创建的所有新对象:

function Object() {
    var obj = this;
    if (window.objectarray === undefined) {
        window.objectarray = [];
    }
    window.objectarray.push(this);
    return this;
}
任何时候页面上的代码使用
新对象()
,它都会被写入
窗口。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();

在这种情况下,如果您使用
newaccount()
创建一个新帐户,将使用私有属性(可能还有方法)创建一个令牌关于
myAccount
的任何内容都不会公开挂在外面。但是“objectToken”和
objPrivate
都将被记录到
窗口。objectarray

永远不要评估json。这是有风险的。使用json解析器,如json2.jsI同意,除非我的json中有可信内容,否则我不应该在不使用解析器的情况下评估它。这不是我的问题……这也不是我的答案;@spender:json2.js确实尝试清理.parse()的输入,但最终使用eval()。@Dave Ward:json2.js在返回“eval”之前检查本机实现。请注意,
({name:'Puff the Dragon',cc:'Credit Card#'})是无效的JSON(即使使用双引号).不允许使用括号。这不是关于用户生成的可执行代码或XSS。这是关于第三方网站上的脚本标记,使用数组构造函数访问登录用户的数据。这是CSRF,而不是XSS。至于您关于数组构造函数不会被数组字面值调用的断言,在最近的浏览器中可能是这样,但有以下几种情况ral较旧的浏览器会出现这个问题,如Firefox2、Opera9和Safari3。我不同意这个问题不涉及XSS,但我会删掉引用它的部分。@nstoertz--整洁。我不能再测试这些了。在这些较新的浏览器中,对象文本不调用对象构造函数,这仍然让我感到惊讶。
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();