FuelphpでCSRF対策

規定のフォームを通さずに来たデータを無視するってヤツ。

作成日:2018-01-11, 更新日:2018-05-02

基本

form送信時のCSRF(Cross-site Request Forgery:リクエスト強要)対策はFuelphpで用意してくれている。

/fuel/app/config/config.php

token_saltは書き換えておく。他はデフォルトでも多分、大丈夫。

~ 略 ~
'security' => array(
  ~ 略 ~
  
  /**
   * A salt to make sure the generated security tokens are not predictable
   */
  'token_salt'            => '〇〇〇〇',
~ 以下、略 ~

formタグの出力(HTML部)

▼inputタグに値を出力させる

<form>
~省略~
<input type="hidden" name="<?php echo \Config::get('security.csrf_token_key');?>" value="<?php echo \Security::fetch_token();?>" />
~省略~
</form>

▼inputタグ自体を生成:複数設置すると「id=〇〇〇」が重複する。HTMLのエラーが出ることになる。気にしないなら問題なし。

<form>
~省略~
<?php echo \Form::csrf(); ?>
~省略~
</form>

受け取ったデータの対策のチェック(PHP)

if ( !\Security::check_token() ) {
   // CSRF攻撃 or CSRFトークンの期限切れ
}

ajax絡み(jquery)

「<?php echo \Config::get('security.csrf_token_key');?>」の値が「fuel_csrf_token」じゃなければ適当に書き換える。

「security.csrf_token_key」の値は「app/config/config.php」を確認する。
コメントされていたら(誰かが書き換えているかもしれないけど)それがデフォルト値だと思う。

<?php echo \Security::js_fetch_token(); ?>
<script>   
   var fd = new FormData();
   fd.append('fuel_csrf_token', fuel_csrf_token());
   
    $.ajax({
      url: 〇〇〇,
      data: fd
    }).done(function(data) {
       ~省略~
</script>

※HTML部に「fuel_csrf_token」が出力されていなければエラーになる。何かすればエラーにならないかも?