読者です 読者をやめる 読者になる 読者になる

PGメモ

非エンジニアの記録

csrf_tokenメモ

symfony1.2は素敵な事に、アプリケーションを作る時にcsrf対策をつけれる。
すごい便利なcsrf対策。少し詳しく見てみた。

フォームでCSRFを防ぐために、フォームの繊維する画面では常にhiddenでCSRF_TOKEN
を持ちまわしている。これのおかげで値が違ったときにエラーを発生させてくれるということだ。素敵

それで、CSRF_TOKENどうやって作ってるの?という話になった
作られているのはsfForm.class.phpである。

  /**
   * Adds CSRF protection to the current form.
   *
   * @param string $secret The secret to use to compute the CSRF token
   */
  public function addCSRFProtection($secret)
  {
    if (false === $secret || (is_null($secret) && !self::$CSRFProtection))
    {
      return;
    }
    if (is_null($secret))
    {
      if (is_null(self::$CSRFSecret))
      {
        self::$CSRFSecret = md5(__FILE__.php_uname());
      }
      $secret = self::$CSRFSecret;
    }
    $token = $this->getCSRFToken($secret);    
  $this->validatorSchema[self::$CSRFFieldName] = new sfValidatorCSRFToken(array('token' => $token));
  $this->widgetSchema[self::$CSRFFieldName] = new sfWidgetFormInputHidden();
  $this->setDefault(self::$CSRFFieldName, $token);
  }

  /**
   * Returns a CSRF token, given a secret.
   *
   * If you want to change the algorithm used to compute the token, you
   * can override this method.
   *
   * @param string $secret The secret string to use (null to use the current secret)
   *                 
   * @return string A token string
   */
  public function getCSRFToken($secret = null)
  {                  
    if (is_null($secret))
    {                
      $secret = self::$CSRFSecret;
    }
                     
    return md5($secret.session_id().get_class($this));
  }

こんな感じになっています
長いのですが、最終的に一番下にあるmd5の部分で作られています

$secretがアプリケーションを作る時にcsrf対策オプションでつけたキーのようなものが入ります。jobeetだとUniqueかな?わからなければapps/アプリ/config/setting.ymlにcsrf_secretという名前で入っています。
ちなみに、この行をコメントアウトしてキャッシュを消せば、csrf対策は無効になります。
session_idはそのまま。ただのsession_idです。
getclassはそこで使われているフォームのクラスですね
この3つを繋げてmd5にしたものがcsrf_tokenとして使われるわけです。

で合ってるのかな?手探り状態のメモでした