为什么不使用会话ID作为XSRF令牌? [英] Why not use session ID as XSRF token?

查看:66
本文介绍了为什么不使用会话ID作为XSRF令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 Play框架将[会话ID的签名版本]用作

Why does Play Framework use [a signed version of the session id] as Cross Site Request Forgery (XSRF/CSRF) prevention token, rather than the session ID itself?

(使用XSRF预防令牌,我的意思是必须在表单提交中包含一个不可思议的值,Web应用程序才能接受该表单.)

(With XSRF prevention token, I mean a magic value that must be included in a form submission, for the webapp to accept the form.)

如果有一个窃听者,他还是会找到XSRF令牌和SID cookie(?).

If there's an eavesdropper s/he'll find both the XSRF token and the SID cookie anyway (?).

如果存在XSS漏洞,则恶意JavaScript代码可以读取XSRF令牌和SID cookie(?).

If there's an XSS exploit, then the malicious JavaScript code can read both the XSRF token and the SID cookie (?).

但是:

  1. 在给定SID的情况下,攻击者无法构造有效的XSRF令牌,因为他/他在签名SID以获得XSRF令牌时没有使用秘密密钥. -但是,如何发生攻击者仅持有SID而不是XSRF令牌的情况?那牵强吗?

  1. An attacker cannot construct a valid XSRF token, given a SID, since s/he doesn't have the secret key used when signing the SID to obtain the XSRF token. -- But how could it happen that an attacker gets hold of only the SID, not the XSRF token? Is that far-fetched?

如果SID是通过HTTP Only cookie发送的,那么即使攻击者找到了XSRF令牌,攻击者也不会拥有SID,也许攻击者确实需要SID吗? -这牵强吗?

If the SID is sent in a HTTP Only cookie, then an attacker wouldn't have the SID even if s/he found the XSRF token, and perhaps the attacker really needs the SID? -- Is this far-fetched?

代码段:

此处Play构造其XSRF令牌(getId返回会话ID): (播放/框架/src/播放/mvc/Scope.java)

Here Play constructs it's XSRF token (getId returns the session ID): (play/framework/src/play/mvc/Scope.java)

    public String getAuthenticityToken() {
        return Crypto.sign(getId());
    }

此处Play会检查<form>是否具有有效的XSRF令牌: (播放/框架/src/播放/mvc/Controller.java)

Here Play checks that a <form> has a valid XSRF token: (play/framework/src/play/mvc/Controller.java)

protected static void checkAuthenticity() {
    if(Scope.Params.current().get("authenticityToken") == null ||
       !Scope.Params.current().get("authenticityToken").equals(
                       Scope.Session.current().getAuthenticityToken())) {
        forbidden("Bad authenticity token");
    }
}

更新:

Play改变了它生成XSRF令牌的方式,现在不再使用SID,而是对随机值进行签名和使用! (我刚刚将我的Pl​​ay Framework Git存储库克隆版本从旧的Play版本1.1更新到了新的1.2.也许我应该在昨天……做到了,嗯.)

Play has changed the way it generates XSRF tokens, now the SID is no longer used, instead a random value is signed and used! (I just updated my Play Framework Git repo clone from old Play version 1.1 to new 1.2. Perhaps I should have done this ... yesterday, hmm.)

    public String getAuthenticityToken() {
        if (!data.containsKey(AT_KEY)) {
            data.put(AT_KEY, Crypto.sign(UUID.randomUUID().toString()));
        }
        return data.get(AT_KEY);
    }

那么,为什么他们要进行此更改?

Well, then why did they do this change?

我找到了提交:
[#669]再次修复,并申请Flash和错误
d6e5dc50ea11fa7ef626cbdf01631595cbdda54c

I found the commit:
[#669] Fix again and apply for Flash and Errors as well
d6e5dc50ea11fa7ef626cbdf01631595cbdda54c

来自问题#669 :
仅在绝对必要时创建会话
在资源的每个请求上都会创建一个会话cookie.只有在会话中确实有数据要存储时,play才应创建会话cookie.

From issue #669:
create session only when absolute necessary
A session cookie is created on every request of a resource. play should only create a session cookie if there is really data to be stored in the session.

因此,他们使用的是随机值,而不是SID,因为可能尚未创建SID.嗯,这就是不使用SID的派生作为XSRF令牌的原因.但是并没有说明他们过去在使用SID时为何签名/签名.

So they're using a random value, not the SID, because the SID might not yet have been created. Well that's a reason not to use a derivative of the SID as XSRF token. But doesn't clarify why they signed/hashed the SID, in the past, when they were using it.

推荐答案

首先要说的是,您可以将会话ID用作CSRF令牌,只要它可以保护您免受罚款CSRF并不会自动创建任何严重的安全漏洞.但是,出于某些合理的原因, OWASP曾经明确建议不要这样做. (他们现在根本不解决这个问题.)

The first thing to say is that you can reuse the session ID as the CSRF token, insofar as it will protect you fine against CSRF and does not automatically create any serious security holes. However, for somewhat sound reasons, OWASP used to explicitly recommend against it. (They now don't address the question at all.)

反对将会话ID重复用作CSRF令牌的论点可以总结如下(关键点以粗体显示,下面有理由):

The argument against reusing the session ID as the CSRF token can be summarized as follows (key points in bold, with justification beneath):

  1. 与攻击者获取的CSRF令牌相比,攻击者获取的会话ID通常是更严重的安全漏洞.

攻击者拥有CSRF令牌(假设尚未将某些其他安全信息,例如会话ID)重新用作CSRF令牌,所获得的全部就是执行CSRF攻击的能力.这给他们带来了两个巨大的限制,如果他们实际上获得了会话ID,就不会有这些限制:

All that an attacker gains from having the CSRF token (assuming that some other secure piece of information, like the session ID, hasn't been reused as the CSRF token) is the ability to perform CSRF attacks. This gives them two huge limitations that they wouldn't have if they actually acquired a session ID:

  • 他们仍然需要用相应的会话令牌吸引用户进入攻击页面(或者让他们阅读攻击电子邮件或在iframe中查看攻击广告等),以任何方式利用CSRF令牌.有了会话ID,他们只需要将其放入浏览器中,然后像使用该用户一样使用该网站即可.
  • 尽管他们可以使用用户的凭据发送请求,但相同来源政策仍然阻止他们查看对这些请求的响应.在实践中,这可能(也可能不会,取决于您所保护的API的结构和攻击者的独创性)意味着,尽管攻击者可以代表用户执行操作,但他们不能获取用户有权查看的敏感信息. (您更关心其中的哪一项取决于具体情况-人们认为攻击者倾向于更喜欢拿走您银行帐户中的内容,而不是仅仅知道那是多少,但他们也宁愿知道您的病史,也不会破坏自己的病史.它.)

  • They still need to lure the user with the corresponding session token to an attack page (or have them read an attack email, or view an attack ad in an iframe, etc.) to exploit the CSRF token in any way at all. With the session ID, they'd just need to put it in their browser and then use the website as if they were that user.
  • While they can send requests using the user's credentials, the Same Origin Policy still prevents them from viewing the responses to those requests. This may (or may not, depending on the structure of the API you're protecting and the attacker's ingenuity) mean in practice that while the attacker can perform actions on the user's behalf, they cannot acquire sensitive information that the user is authorized to view. (Which of these you care more about depends upon the context - one assumes that an attacker would tend to prefer taking the contents of your bank account to merely knowing how much that is, but that they'd also rather know your medical history than vandalise it.)

CSRF令牌可能比会话ID更容易获得攻击者

  • XSS attacks are likely to permit an attacker to acquire the CSRF token, since it's common practice to bake it into the DOM (e.g. as the value of an <input> element in a <form>. Session cookies, on the other hand, can be kept secret even in the face of a successful XSS attack using the HttpOnly flag, demanding more up-front work from an attacker to usefully exploit an XSS vulnerability.
  • If the CSRF token is being sent back to the server as a request parameter rather than a custom HTTP header (guaranteed to be the case when including it in ordinary HTML <form> submits), then web server access logs will generally log the CSRF token on GET requests (as it's part of the URL). Thus an attacker who manages to view the access log would be able to acquire many CSRF tokens.
  • Pages or scripts that the CSRF token is baked into may be cached in the user's browser, permitting an attacker to retrieve them from the cache (conceivably relevant after the user has, for example, used a public machine in a library or internet cafe, and then either cleared their cookies but not their cache, or used a 'Log Out' button that removes their session cookie from the browser without invalidating it server-side).

但是,如果您将会话ID用作CSRF令牌,那么任何允许他们获取CSRF令牌的攻击也会自动为其提供会话ID.

因此,您不应将CSRF令牌用作会话ID,因为它会使会话ID更容易受到攻击.

说实话,我将以上所有内容都看作是理论上的关注,而不是实践上的关注.参数中的弱点是点2;我能想到的唯一现实漏洞可以用于获取CSRF令牌,但不能用于获取会话cookie仍然是严重的漏洞.如果您的网站上存在XSS漏洞,或者攻击者可以访问您极为奇怪的服务器日志,那么无论如何,您很可能会被完全搞砸.在我去过的大多数图书馆和网吧中,工作人员并不精通安全性,很容易安装未检测到的键盘记录程序,而只是收集密码-无需攻击者进入努力等待人们使用计算机,然后翻录其浏览器缓存的内容.

To be honest, I kind of regard everything above as more of a theoretical concern than a practical one. The weak point in the argument is point 2; the only realistic vulnerabilities I can think of that could be used for acquiring CSRF tokens but not for acquiring session cookies are still really serious vulnerabilities. If you have an XSS hole on your site, or an attacker has access to your freaking server logs, chances are you're totally fucked anyway. And in most libraries and internet cafes I've been to, the staff were not security-savvy and it'd be pretty easy to install a keylogger undetected and just harvest passwords - there'd be no need for an attacker to go to the effort of waiting for people to use the machine and then ripping the contents of their browser cache.

但是,除非您的情况使您难以为CSRF与随机会话ID一起存储额外的随机令牌,为什么不为获得给您的适度安全利益而仍然这样做呢?

However, unless your circumstances somehow make it difficult to store an additional random token for CSRF alongside the random session ID, why not just do it anyway for whatever modest security benefit it gives you?

这篇关于为什么不使用会话ID作为XSRF令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆