Si notre site Web voit l'utilisateur connecté à Facebook avec l'ID d'utilisateur 678678678 dans le cookie, comment pouvons-nous savoir que ce cookie n'est pas falsifié ?

StackOverflow https://stackoverflow.com/questions/4002616

  •  25-09-2019
  •  | 
  •  

Question

Je pense que si nous appelons Facebook en utilisant l'API REST ou Graph, nous saurons si c'est faux car il reviendra en disant fausse session / auth_token / access_token.Mais que se passe-t-il si nous affichons nos propres informations de base de données, telles que la « liste des produits préférés de l'utilisateur », alors nous n'appelons pas Facebook mais affichons les données de notre base de données.Comment savons-nous qu'il s'agit bien de l'utilisateur et non de quelqu'un qui simule le cookie ?

Était-ce utile?

La solution

Lorsque vous lisez un cookie avec Facebook, il contient une valeur appelée « sig ».Avec cette valeur, les autres valeurs de cookie et le secret de votre application, vous hachez le contenu du cookie et le validez par rapport à la signature.S'ils correspondent, alors le cookie est valide.Vous pouvez faire confiance à ce résultat car seuls vous et Facebook avez accès au secret de l'application.Voici un exemple de la façon dont le SDK PHP de Facebook le fait.Tout SDK Facebook respectable fera tout cela pour vous en interne.

/**
   * Validates a session_version=3 style session object.
   *
   * @param Array $session the session object
   * @return Array the session object if it validates, null otherwise
   */
  protected function validateSessionObject($session) {
    // make sure some essential fields exist
    if (is_array($session) &&
        isset($session['uid']) &&
        isset($session['access_token']) &&
        isset($session['sig'])) {
      // validate the signature
      $session_without_sig = $session;
      unset($session_without_sig['sig']);
      $expected_sig = self::generateSignature(
        $session_without_sig,
        $this->getApiSecret()
      );
      if ($session['sig'] != $expected_sig) {
        self::errorLog('Got invalid session signature in cookie.');
        $session = null;
      }
      // check expiry time
    } else {
      $session = null;
    }
    return $session;
  }

Voici la même chose en C# (Kit de développement logiciel C# Facebook):

 /// <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();
    }

Autres conseils

La seule chose que vous pouvez faire confiance est session_key pour les anciens et api REST access_token pour API Graph. Une fois que vous avez obtenu, passez à un côté serveur à la demande de vos données. Sur l'appel côté serveur facebook api et obtenir userid en cours. Une fois que vous avez obtenu userid vous pouvez le stocker dans une session et de l'utiliser plus tard.

ne pas stocker dans un cookie. Mettez-le dans une variable de session, de cette façon vous avez le contrôle

Ne pas mettre un nom d'utilisateur dans un cookie. Le cookie de session doit juste être un nombre aléatoire qui correspond à un enregistrement dans la base de données de session côté serveur. Toutes les données associées à cette session ne sont stockées côté serveur.

De cette façon, afin de simuler une session, un attaquant aurait deviner un nombre aléatoire qui en fait utilisé à ce moment-là. Étant donné qu'il ya beaucoup de nombres aléatoires et les sessions arrivent à échéance, qui est presque impossible.

Il y a quelques approches ici.

Inefficace: Chaque fois que vous effectuez une opération authentifiée, saisir le cookie de FB et utiliser les données pour faire un appel API factice pour voir que le jeton d'accès est valide et correspond à l'utilisateur (c.-à-grab / moi champs = id?) .

Plus efficace: La première fois que vous voyez un cookie de FB pour un utilisateur, stocker ce cookie dans une session côté serveur pour l'utilisateur (avec une session suffisamment à disque deviner ID transmis au client dans un cookie) .

Une autre approche, et ne nécessite pas l'état de session côté serveur: La première fois que vous voyez un cookie de FB pour un utilisateur, HMAC le cookie en utilisant un secret que vos serveurs ont, et de stocker que hachage dans un cookie. Ensuite, vous pouvez vérifier s'il y a un hachage valide du cookie FB, et si oui, vous faites confiance. Sinon, vous retombez à la validation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top