简体   繁体   English

Facebook JS SDK:纯文本和安全性的access_token

[英]Facebook JS SDK: access_token in plain text and security

When user logs into facebook using the popup displayed by FB.login() call, JS SDK plants to my domain a cookie containing oauth access_token in plain text. 当用户使用FB.login()调用显示的弹出窗口登录facebook时,JS SDK会在我的域中植入一个包含纯文本oauth access_token的cookie。 Then, this cookie is being sent to my server with every subsequent request - and it's pretty obvious that not every request uses https . 然后,这个cookie随着每个后续请求被发送到我的服务器 - 很明显,并非每个请求都使用https

Isn't this a security problem? 这不是一个安全问题吗? If so, then how to solve it? 如果是这样,那怎么解决呢?

It isn't a problem because you can verify the authenticity of the cookie. 这不是问题,因为您可以验证cookie的真实性。 Facebook includes a value called sig with each cookie. Facebook在每个cookie中都包含一个名为sig的值。 I won't go into full details, but basically, you append your API secret to the cookie, remove the sig value, hash the cookie value and verify that the hash matches the sig. 我不会详细介绍,但基本上,您将API秘密附加到cookie,删除sig值,散列cookie值并验证散列是否与sig匹配。 Because you and Facebook are the only ones that know the value of the API secret you can be sure that the cookie wasn't tampered with. 因为您和Facebook是唯一知道API秘密价值的人,所以可以确保cookie没有被篡改。

The other side of the things, the user viewing the contents of the cookie, doesnt matter either. 事情的另一方面,用户查看cookie的内容,也无关紧要。 The cookie only contains an access token associated with that user. cookie仅包含与该用户关联的访问令牌。 If the user tries to tamper with the cookie the only thing that will happen is they will make the cookie invalid. 如果用户试图篡改cookie,那么唯一会发生的事情就是使cookie无效。 And their access token only gets them access to their own account anyway. 而且他们的访问令牌只能让他们访问自己的帐户。

The most important thing is verifying the cookie is authentic. 最重要的是验证cookie是真实的。 Many people dont do this and do cause huge security issues. 许多人不这样做,确实造成了巨大的安全问题。 For example, the cookie contains the facebook user id. 例如,cookie包含facebook用户ID。 Say I get that user Id then ask my user for their credit card. 假设我得到该用户ID然后询问我的用户他们的信用卡。 If I store that credit card with that user ID, but dont validate the cookie, anyone could come in and change the user id value in there cookie and get access to private data. 如果我使用该用户ID存储该信用卡,但不验证cookie,则任何人都可以进入并更改cookie中的用户ID值并访问私有数据。 However, if I verify the cookie with the API secret, I would know if the cookie was tampered with. 但是,如果我使用API​​密钥验证cookie,我会知道cookie是否被篡改。

Here is how we validate the cookie in my Facebook C# SDK (http://facebooksdk.codeplex.com): 以下是我们在Facebook C#SDK(http://facebooksdk.codeplex.com)中验证cookie的方法:

        /// <summary>
        /// Validates a session_version=3 style session object.
        /// </summary>
        /// <param name="session">The session to validate.</param>
        protected override void ValidateSessionObject(FacebookSession session)
        {
            if (session == null)
            {
                return;
            }

            var signature = this.GenerateSignature(session);
            if (session.Signature == signature.ToString())
            {
                return;
            }

            session = null;
        }

        /// <summary>
        /// Generates a MD5 signature for the facebook session.
        /// </summary>
        /// <param name="session">The session to generate a signature.</param>
        /// <returns>An MD5 signature.</returns>
        /// <exception cref="System.ArgumentNullException">If the session is null.</exception>
        /// <exception cref="System.InvalidOperationException">If there is a problem generating the hash.</exception>
        protected override string GenerateSignature(FacebookSession session)
        {
            var args = session.Dictionary;
            StringBuilder payload = new StringBuilder();
            var parts = (from a in args
                         orderby a.Key
                         where a.Key != "sig"
                         select string.Format(CultureInfo.InvariantCulture, "{0}={1}", a.Key, a.Value)).ToList();
            parts.ForEach((s) => { payload.Append(s); });
            payload.Append(this.ApiSecret);
            byte[] hash = null;
            using (var md5 = System.Security.Cryptography.MD5CryptoServiceProvider.Create())
            {
                if (md5 != null)
                {
                    hash = md5.ComputeHash(Encoding.UTF8.GetBytes(payload.ToString()));
                }
            }

            if (hash == null)
            {
                throw new InvalidOperationException("Hash is not valid.");
            }

            StringBuilder signature = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                signature.Append(hash[i].ToString("x2", CultureInfo.InvariantCulture));
            }

            return signature.ToString();
        }

An attacker, who is able to sniff the network traffic (eg a wireless lan), can read the cookie. 能够嗅探网络流量(例如无线局域网)的攻击者可以读取cookie。 And pretend to be the person it was created for. 并假装成为它创建的人。

This is not really an issue because the same attack works on the facebook pages itself: Only the username/password - authentication is done via https. 这不是一个真正的问题,因为同样的攻击在Facebook页面本身上起作用:只有用户名/密码 - 通过https进行身份验证。 All following pages use unencrypted http, which contain the cookie. 以下所有页面都使用未加密的http,其中包含cookie。

There is an easy-to-use Firefox extension which allows steeling of cookies, if you are able to sniff the network traffic: http://codebutler.com/firesheep 有一个易于使用的Firefox扩展,如果你能够嗅探网络流量,它可以实现cookie的精简: http//codebutler.com/firesheep

PS: stackoverflow.com is vulnerable, too. PS:stackoverflow.com也很脆弱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM