🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CodeIgniter

CodeIgniterは、PHP向けオープンソースのWebアプリケーションフレームワークです。CodeIgniterは覚える構文が少なく、自由度も高いため、PHPを理解していれば構築が簡単です。

CSRF

クロスサイトリクエストフォージェリ (Cross site request forgeries、CSRF)は、 外部Webページから、HTTPリクエストによって、 Webサイトの機能の一部が実行されてしまうWWWにおける攻撃手法です。

Q&A

解決済

1回答

2431閲覧

codeigniter ver.3のcsrfの使い方がわからない

muramura5011

総合スコア0

CodeIgniter

CodeIgniterは、PHP向けオープンソースのWebアプリケーションフレームワークです。CodeIgniterは覚える構文が少なく、自由度も高いため、PHPを理解していれば構築が簡単です。

CSRF

クロスサイトリクエストフォージェリ (Cross site request forgeries、CSRF)は、 外部Webページから、HTTPリクエストによって、 Webサイトの機能の一部が実行されてしまうWWWにおける攻撃手法です。

0グッド

0クリップ

投稿2021/01/29 06:01

編集2021/01/29 08:37

前提・実現したいこと

codeigniter3で csrfの設定を行いたいです。

発生している問題・エラーメッセージ

(application\config\config.phpの「$config['csrf_protection'] = TRUE;」に設定) 画面ページAのFormに「<input type="hidden" name="csrf_test_name" value="9d3e28d9e57ce0ee7c194280a066e3d1" />」 が出力されているのを確認し、遷移先のページBでsessionに入れた値と比較しようとしたら、 $_POST['csrf_test_name']がnullでした。 何かの手違いかと思い、「print_r($_POST)」で確認したところ、 $_POST['csrf_test_name']がありませんでした。 web開発が初心者なので、誤解して覚えているかもしれませんが、 phpのcsrf対策は、formにhiddenタグでハッシュ値を埋め込み、 同値をセッションにも入れ、次ページでセッションの値とpostされた値を比較するつくりかと 思っていたのですが、codeigniterは、こういった方法ではないのでしょうか?

該当のソースコード

画面ページAのForm <form action="http://localhost/codeigniter/index.php/form" method="post" accept-charset="utf-8"> <input type="hidden" name="csrf_test_name" value="9d3e28d9e57ce0ee7c194280a066e3d1" /> <h5>ユーザ名</h5> <input type="text" name="username" value="" size="50" /> <h5>パスワード</h5> <input type="text" name="password" value="" size="50" /> <h5>パスワード確認</h5> <input type="text" name="passconf" value="" size="50" /> <h5>メールアドレス</h5> <input type="text" name="email" value="" size="50" /> <div><input type="submit" value="Submit" /></div> </form> 次ページで表示されたprint_r($_POST) Array ( [username] => test [password] => test [passconf] => test [email] => test@gmail.com )

試したこと

application\config\config.phpの「$config['csrf_protection'] = FALSE;」に設定し、
画面ページAのFormに
<input type="hidden" name="csrf_test_name" value="9d3e28d9e57ce0ee7c194280a066e3d1" /> 」を
追加して行ったところ、
次ページで表示されたprint_r($_POST)は、
Array ( [username] => test [password] => test [passconf] => test [email] => test@gmail.com [csrf_test_name] => 9d3e28d9e57ce0ee7c194280a066e3d1 )
となりました。(あたりまえでしょうが。)

補足情報(FW/ツールのバージョンなど)

CodeIgniter-3.1.11
PHP Version 7.2.34
です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/01/29 07:53

$POSTという変数は質問者さんが定義したんですか?
muramura5011

2021/01/29 08:36

大変申し訳ございません。 $POST['csrf_test_name']ではなく、$_POST['csrf_test_name']でした。 記事の訂正いたします。
guest

回答1

0

自己解決

CodeIgniter\system\core\Security.phpに記述がありました。

class CI_Security { ~~~~~~~~~~~~~~~~~~~~~~ protected $_csrf_token_name = 'ci_csrf_token'; ~~~~~~~~~~~~~~~~~~~~~~ public function csrf_verify() { // If it's not a POST request we will set the CSRF cookie if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') { return $this->csrf_set_cookie(); } // Check if URI has been whitelisted from CSRF checks if ($exclude_uris = config_item('csrf_exclude_uris')) { $uri = load_class('URI', 'core'); foreach ($exclude_uris as $excluded) { if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), $uri->uri_string())) { return $this; } } } // Check CSRF token validity, but don't error on mismatch just yet - we'll want to regenerate $valid = isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]) && is_string($_POST[$this->_csrf_token_name]) && is_string($_COOKIE[$this->_csrf_cookie_name]) && hash_equals($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name]); // We kill this since we're done and we don't want to pollute the _POST array unset($_POST[$this->_csrf_token_name]);  ←--------この部分 // Regenerate on every submission? if (config_item('csrf_regenerate')) { // Nothing should last forever unset($_COOKIE[$this->_csrf_cookie_name]); $this->_csrf_hash = NULL; } $this->_csrf_set_hash(); $this->csrf_set_cookie(); if ($valid !== TRUE) { $this->csrf_show_error(); } log_message('info', 'CSRF token verified'); return $this; } ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ } コード

csrf_verifyメソッドでcrsfの対策ができるのですね。

つまり、application\config\config.phpの「$config['csrf_protection'] = TRUE」
にするだけで、画面遷移をしたときにCI_Securityのcsrf_verifyメソッドが動作し判定するのですね。

あまりにも無知すぎました。
恥ずかしい質問をしてしまいましたが、勉強になりました。
お騒がせしました。

投稿2021/01/29 09:52

muramura5011

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問