这是足够的,以防止跨站请求伪造一个Ajax驱动的应用程序?这是、应用程序、以防止、Ajax

2023-09-10 15:59:23 作者:噬心

我工作的一个完全Ajax驱动的应用程序,其中的所有请求通过什么基本上相当于一个主控制器,它在其裸露的骨头,看起来像这样:

I'm working on a completely ajax-driven application where all requests pass through what basically amounts to a main controller which, at its bare bones, looks something like this:

if(strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    fetch($page);
}

这是一般足以防止跨站请求伪造?

Is this generally sufficient to protect against cross-site request forgeries?

这是相当不方便,旋转令牌时,整个页面不刷新与每个请求。

It's rather inconvenient to have a rotating token when the entire page isn't refreshed with each request.

我想我可以传递和更新独特的标记与每个请求一个全局javascript变量 - 但不知为什么,感觉笨拙,似乎天生不安全反正

I suppose I could pass and update unique token as a global javascript variable with every request -- but somehow that feels clumsy and seems inherently unsafe anyway.

编辑 - 也许是一个静态的令牌,如用户的UUID,会比没有好

EDIT - Perhaps a static token, like the user's UUID, would be better than nothing?

编辑#2 - 作为的的鲁克的人士指出,这可能是一个吹毛求疵的问题。我读过的猜测是双向的,听到远处窃窃私语早期版本的闪存是可利用的为这种恶作剧。因为我什么都不知道了,我把一个赏金的人谁可以解释如何,这是一个跨站请求伪造风险。否则,我给它的 Artefacto 的。谢谢你。

EDIT #2 - As The Rook pointed out, this might be a hair-splitting question. I've read speculation both ways and heard distant whispers about older versions of flash being exploitable for this kind of shenanigans. Since I know nothing about that, I'm putting up a bounty for anyone who can explain how this is a CSRF risk. Otherwise, I'm giving it to Artefacto. Thanks.

推荐答案

我会说这是不够的。如果允许跨域请求,你会无论如何注定,因为攻击者可以使用JavaScript来获取CSRF令牌,并把它用在伪造的请求。

I'd say it's enough. If cross-domain requests were permitted, you'd be doomed anyway because the attacker could use Javascript to fetch the CSRF token and use it in the forged request.

一个静态的标记不是一个好主意。令牌应该每个会话生成至少一次。

A static token is not a great idea. The token should be generated at least once per session.

EDIT2 迈克是不正确毕竟,对不起。我还没有看过我联系到正确的页面。它说:

EDIT2 Mike is not right after all, sorry. I hadn't read the page I linked to properly. It says:

一个简单的跨站点请求是指:[...]   不设置自定义头部与HTTP请求(如X-修改等。)

A simple cross-site request is one that: [...] Does not set custom headers with the HTTP Request (such as X-Modified, etc.)

因此​​,如果您设置 X-要求 - 以,要求必须是pre-飞行,除非你到pre-飞行回应选项请求授权跨站点请求,它不会得到通过。

Therefore, if you set X-Requested-With, the request has to be pre-flown, and unless you respond to pre-flight OPTIONS request authorizing the cross-site request, it won't get through.

修改迈克是正确的,作为火狐3.5,跨站点XMLHtt prequests是许可。因此,你还必须检查原产地头,当它的存在,匹配您的网站。

EDIT Mike is right, as of Firefox 3.5, cross-site XMLHttpRequests are permitted. Consequently, you also have to check if the Origin header, when it exists, matches your site.

if (array_key_exists('HTTP_ORIGIN', $_SERVER)) {
    if (preg_match('#^https?://myserver.com$#', $_SERVER['HTTP_ORIGIN'])
        doStuff();
}
elseif (array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) &&
        (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'))
    doStuff(); 
 
精彩推荐
图片推荐