簡體   English   中英

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

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

當用戶使用FB.login()調用顯示的彈出窗口登錄facebook時,JS SDK會在我的域中植入一個包含純文本oauth access_token的cookie。 然后,這個cookie隨着每個后續請求被發送到我的服務器 - 很明顯,並非每個請求都使用https

這不是一個安全問題嗎? 如果是這樣,那怎么解決呢?

這不是問題,因為您可以驗證cookie的真實性。 Facebook在每個cookie中都包含一個名為sig的值。 我不會詳細介紹,但基本上,您將API秘密附加到cookie,刪除sig值,散列cookie值並驗證散列是否與sig匹配。 因為您和Facebook是唯一知道API秘密價值的人,所以可以確保cookie沒有被篡改。

事情的另一方面,用戶查看cookie的內容,也無關緊要。 cookie僅包含與該用戶關聯的訪問令牌。 如果用戶試圖篡改cookie,那么唯一會發生的事情就是使cookie無效。 而且他們的訪問令牌只能讓他們訪問自己的帳戶。

最重要的是驗證cookie是真實的。 許多人不這樣做,確實造成了巨大的安全問題。 例如,cookie包含facebook用戶ID。 假設我得到該用戶ID然后詢問我的用戶他們的信用卡。 如果我使用該用戶ID存儲該信用卡,但不驗證cookie,則任何人都可以進入並更改cookie中的用戶ID值並訪問私有數據。 但是,如果我使用API​​密鑰驗證cookie,我會知道cookie是否被篡改。

以下是我們在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();
        }

能夠嗅探網絡流量(例如無線局域網)的攻擊者可以讀取cookie。 並假裝成為它創建的人。

這不是一個真正的問題,因為同樣的攻擊在Facebook頁面本身上起作用:只有用戶名/密碼 - 通過https進行身份驗證。 以下所有頁面都使用未加密的http,其中包含cookie。

有一個易於使用的Firefox擴展,如果你能夠嗅探網絡流量,它可以實現cookie的精簡: http//codebutler.com/firesheep

PS:stackoverflow.com也很脆弱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM