4

私は自分のウェブサイトmydomain.com/forumsで、VanillaFrameworkを使用するフォーラムを運営しています。

ただし、そのフォーラムに登録しているユーザーが、mydomain.com/blogにある私のサイトの他のページにコメントを残せるようにしたいと思います。したがって、ユーザーがログインしていることを確認する方法、またはログインしていない場合は、Vanillaログインボックスをユーザーに提供する方法が必要です。

私のバニラコードは私のブログページにまったく載っていないので、ある種の追加のスクリプトが必要です。たくさん掘り下げた後、私はこれをオンラインで見つけました。https: //gist.github.com/lincolnwebs/700805これは、ログインしている場合はuser_idを、ログインしていない場合は0を示します。バニラフレームワーク全体を含める必要があります。

スクリプトは、ユーザーのブラウザでCookieの値をチェックしているようです。誰かがCookieの価値を偽って、誰かのアカウントにアクセスする可能性はありますか?

比較的初心者として、これがユーザーがログインしていることを確認するための安全で安全な方法であるかどうかを誰かが説明できますか?これを見つけるのに何年もかかりました、そしてそれは隠されている/公表されていないようです。また、静的関数内で$ thisを使用するため、スクリプトは100%完全ではありません。

ありがとう

<?php
/**
 * @copyright Vanilla Forums Inc.
 * @license GNU GPL2
 */

/**
 * Instantiating this class will store current user's ID from cookie as $this->UserID.
 */
class VanillaIdentity {

   # Copy these from Vanilla config
   public $CookieName = 'Vanilla';
   public $CookieSalt = ''; 
   public $CookieHashMethod = 'md5';
   public $UserID = 0;

   /**
    * Returns the unique id assigned to the user in the database (retrieved
    * from the session cookie if the cookie authenticates) or FALSE if not
    * found or authentication fails.
    *
    * @return int
    */
   public function __construct() {         
      if (!$this->_CheckCookie($this->CookieName)) return 0;

      list($UserID, $Expiration) = $this->GetCookiePayload($this->CookieName);

      if (!is_numeric($UserID) || $UserID < -2) // allow for handshake special id
         $this->UserID = 0;
      else
         $this->UserID = $UserID;
   }

   public static function GetCookiePayload($CookieName) {
      if (!self::CheckCookie($CookieName)) return FALSE;

      $Payload = explode('|', $_COOKIE[$CookieName]);

      // Get rid of check fields like HashKey, HMAC and Time
      array_shift($Payload);
      array_shift($Payload);
      array_shift($Payload);

      return $Payload;
   }

   protected function _CheckCookie($CookieName) {
      return self::CheckCookie($CookieName);
   }

   public static function CheckCookie($CookieName) {

      if (empty($_COOKIE[$CookieName])) {
         return FALSE;
      }

      $CookieHashMethod = $this->CookieHashMethod;
      $CookieSalt = $this->CookieSalt;

      $CookieData = explode('|', $_COOKIE[$CookieName]);
      if (count($CookieData) < 5) {
         return FALSE;
      }

      list($HashKey, $CookieHash, $Time, $UserID, $Expiration) = $CookieData;
      if ($Expiration < time() && $Expiration != 0) {
         return FALSE;
      }

      $Key = self::_Hash($HashKey, $CookieHashMethod, $CookieSalt);
      $GeneratedHash = self::_HashHMAC($CookieHashMethod, $HashKey, $Key);

      if ($CookieHash != $GeneratedHash) {
         return FALSE;
      }

      return TRUE;
   }

   /**
    * Returns $this->_HashHMAC with the provided data, the default hashing method
    * (md5), and the server's COOKIE.SALT string as the key.
    *
    * @param string $Data The data to place in the hash.
    */
   protected static function _Hash($Data, $CookieHashMethod, $CookieSalt) {
      return Gdn_CookieIdentity::_HashHMAC($CookieHashMethod, $Data, $CookieSalt);
   }

   /**
    * Returns the provided data hashed with the specified method using the
    * specified key.
    *
    * @param string $HashMethod The hashing method to use on $Data. Options are MD5 or SHA1.
    * @param string $Data The data to place in the hash.
    * @param string $Key The key to use when hashing the data.
    */
   protected static function _HashHMAC($HashMethod, $Data, $Key) {
      $PackFormats = array('md5' => 'H32', 'sha1' => 'H40');

      if (!isset($PackFormats[$HashMethod]))
         return false;

      $PackFormat = $PackFormats[$HashMethod];
      // this is the equivalent of "strlen($Key) > 64":
      if (isset($Key[63]))
         $Key = pack($PackFormat, $HashMethod($Key));
      else
         $Key = str_pad($Key, 64, chr(0));

      $InnerPad = (substr($Key, 0, 64) ^ str_repeat(chr(0x36), 64));
      $OuterPad = (substr($Key, 0, 64) ^ str_repeat(chr(0x5C), 64));

      return $HashMethod($OuterPad . pack($PackFormat, $HashMethod($InnerPad . $Data)));
   }

}
4

1 に答える 1

2

私はバニラと JavaScript の専門家ではありません。私は HTTP 認証と SSO をよく理解しています。いくつかの質問を明確にしようと思います。

まず、HTTP 認証の後、アプリケーションはユーザー Cookie をブラウザーに設定します。次のリクエストで、ブラウザはサーバーに Cookie を送信します。Cookie のセット中にどのパスが使用されたかが重要であることに注意してください。パスが「/」の場合、ブラウザはサーバー上のすべてのアプリケーションに Cookie を送信します。

Cookie がハイジャックされ、アプリケーションへのアクセスに使用される可能性があります。ハッカーが Cookie を復号化できない可能性があることに注意してください。そのまま使用してください。詳細については、次のリンクを参照してください: https://www.owasp.org/index.php/Session_hijacking_attack。セッションの乗っ取りを防ぐには、HTTPS を使用できます。

問題を解決するには、1) mydomain.com/forums と mydomain.com/blog の両方に同じユーザー リポジトリを使用します。この場合、ユーザー「bob」は両方のアプリケーションで同じユーザーになります。2) Vanilla がパス「/」を使用して Cookie を設定するようにするには、この場合、ブラウザは mydomain.com/forums と mydomain.com/blog の両方に Cookie を送信します。

次の Vanilla プラグインを見つけました。問題を完全に解決できる可能性があります: http://vanillaforums.org/page/SingleSignOn

それが役に立てば幸い。追加の説明が必要な場合はコメントしてください。

于 2013-03-13T10:51:52.760 に答える