Facebook JS SDK: access_token в виде простого текста и безопасность - PullRequest
3 голосов
/ 01 декабря 2010

Когда пользователь входит в Facebook, используя всплывающее окно, отображаемое вызовом FB.login(), JS SDK устанавливает в мой домен файл cookie, содержащий oauth access_token в виде простого текста. Затем этот файл cookie отправляется на мой сервер с каждым последующим запросом - и совершенно очевидно, что не каждый запрос использует https.

Разве это не проблема безопасности? Если так, то как это решить?

Ответы [ 2 ]

3 голосов
/ 01 декабря 2010

Это не проблема, потому что вы можете проверить подлинность куки. Facebook включает значение, называемое sig, с каждым файлом cookie. Я не буду вдаваться в подробности, но в основном вы добавляете свой секрет API в cookie, удаляете значение sig, хешируете значение cookie и проверяете, совпадает ли хеш с sig. Поскольку вы и Facebook - единственные, кто знает значение секрета API, вы можете быть уверены, что файл cookie не был подделан.

Другая сторона вещей, пользователь, просматривающий содержимое куки, также не имеет значения. Файл cookie содержит только маркер доступа, связанный с этим пользователем. Если пользователь попытается изменить файл cookie, единственное, что произойдет, - он сделает файл cookie недействительным. А их токен доступа в любом случае только дает им доступ к своей учетной записи.

Самое главное, чтобы файл cookie был подлинным. Многие люди не делают этого и вызывают огромные проблемы с безопасностью. Например, файл cookie содержит идентификатор пользователя Facebook. Скажем, я получил идентификатор этого пользователя, а затем попросил его кредитной карты. Если я храню эту кредитную карту с этим идентификатором пользователя, но не проверяю файл cookie, любой может зайти и изменить значение идентификатора пользователя в этом файле cookie и получить доступ к личным данным. Однако, если я проверю файл cookie с секретом API, я узнаю, был ли файл cookie изменен.

Вот как мы проверяем файл cookie в моем Facebook C # SDK (http://facebooksdk.codeplex.com):

        /// <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();
        }
2 голосов
/ 01 декабря 2010

Злоумышленник, способный перехватить сетевой трафик (например, по беспроводной сети), может прочитать файл cookie.И притворись тем, для кого он был создан.

На самом деле это не проблема, потому что та же атака работает на самих страницах facebook: только имя пользователя / пароль - аутентификация выполняется через https.На всех следующих страницах используется незашифрованный http, содержащий cookie.

Существует простое в использовании расширение Firefox, которое позволяет использовать cookie-файлы, если вы можете прослушивать сетевой трафик: http://codebutler.com/firesheep

PS: stackoverflow.com также уязвим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...