TOOL更新_63.クロスサイトリクエストフォージェリ対策として、DB追加、更新、削除の画面でトークンチェックを行う。作成完了。
TOOL更新_63.クロスサイトリクエストフォージェリ対策http://d.hatena.ne.jp/kazpgm/20090403/1238773943として、DB追加、更新、削除の画面でトークンチェックを行う。作成完了。 (ダブルクリック防止も同時に行っている。)
http://d.hatena.ne.jp/kazpgm/20090524/1243113458 、http://d.hatena.ne.jp/kazpgm/20090525/1243262315(5月24、25に一度作ったが、いろいろな理由でボツにした。)本日このロジックで自動作成することにした。
■TokenHandle.php (トークンチェッククラス)
<?php //トークンチェッククラス class TokenHandle { // トークンHidden取得 function getTokenHtml($base = "") { // トークン作成 $latest_token = md5(uniqid(rand(),TRUE)); if (!is_array($_SESSION['KAZ_TOOL_token'])) { // トークンは配列で保存する $_SESSION['KAZ_TOOL_token'] = array(); } else { if (count($_SESSION['KAZ_TOOL_token']) > 9) { // トークンは直近10個保存 array_shift($_SESSION['KAZ_TOOL_token']); } } if (!is_array($_SESSION['KAZ_TOOL_token_time'])) { // トークン時間は配列で保存する $_SESSION['KAZ_TOOL_token_time'] = array(); } else { if (count($_SESSION['KAZ_TOOL_token_time']) > 9) { // トークン時間は直近10個保存 array_shift($_SESSION['KAZ_TOOL_token_time']); } } $_SESSION['KAZ_TOOL_token'][$latest_token] = $latest_token; // トークン保存 $_SESSION['KAZ_TOOL_token_time'][$latest_token] = time(); // トークン時間保存 if ($base == "") { return '<input type="hidden" name="KAZ_TOOL_token" value="'. $latest_token .'" />' ; } else { return 'KAZ_TOOL_token='. $latest_token; } } // トークンチェック function isTokenValid($mode, $userFlg = true) { $modeMach = false; // トークンチェックフラグ初期化 $mode_ary = explode(',', 'ins_do,upd_do,del_do' ); // トークンチェック対象モード配列 for($i = 0; $i < count($mode_ary); $i++) { if (trim($mode_ary[$i]) == $mode) { // 'ins_do,upd_do,del_do'の中にあれば $modeMach = true; // トークンチェックする break; } } if ($modeMach == true) { // トークンチェックする場合 if (!empty($_SESSION['KAZ_TOOL_token']) && is_array($_SESSION['KAZ_TOOL_token']) && $_REQUEST['KAZ_TOOL_token'] == $_SESSION['KAZ_TOOL_token'][$_REQUEST['KAZ_TOOL_token'] ]) { $token_age = time() - $_SESSION['KAZ_TOOL_token_time'][$_REQUEST['KAZ_TOOL_token'] ]; if (($userFlg == false && $token_age > (180 * 60)) || // 管理者は3時間OK ($userFlg == true && $token_age > (60 * 60))) { // ユーザは1時間OK(深い理由はない) // OK:トークン削除 unset($_SESSION['KAZ_TOOL_token'][$_REQUEST['KAZ_TOOL_token'] ]); unset($_SESSION['KAZ_TOOL_token_time'][$_REQUEST['KAZ_TOOL_token'] ]); } } else { return false; } return true; } // OK return true; } } ?>
■プログラムに追加
・管理者側: require_once('TokenHandle.php'); if (TokenHandle::isTokenValid($mode, false) == false) { // 管理者側 // トークンチェックエラー場合 echo 'Message: ' . 'The token error occurred. ' . "<br />\n"; exit; } unset($_REQUEST['KAZ_TOOL_token']); ・ユーザ側: require_once('TokenHandle.php'); if (TokenHandle::isTokenValid($mode, true) == false) { // ユーザ側 // トークンチェックエラー場合 echo 'Message: ' . 'The token error occurred. ' . "<br />\n"; exit; } unset($_REQUEST['KAZ_TOOL_token']);
■htmlプログラムに追加
require_once('TokenHandle.php'); <?= TokenHandle::getTokenHtml(); ?>
■2度押しした場合トークンチェックエラーになってしまうので、このJavaScriptで2度押しできないようにしておく。
<=7/23 トークンは直近10個残すようにしたので、2度押しでのトークンチェックエラーは起きないということに気づいた。
・htmlに追加、修正 例):itemUaddConfirmView.htm_ <script type="text/javascript" src="/kaz01u/admin/js/kaz.js"></script> <a href="javascript:do_Submit_CLK2('ins_do');"><img src="/kaz01u/img/btn/btn_entry.gif" alt="登録" width="61" height="22" border="0" class="right5" /></a>
■kaz.js を新規で作成する。
var doubleClick_flg = true; //Submit制御(DoubleClick制御あり) function do_Submit_Clk1() { if (doubleClick_flg == true) { window.setTimeout(function() { doubleClick_flg = false; }, 1); window.setTimeout(function() { doubleClick_flg = true; }, 1000); document.frm.submit(); } else { return; false; } } //Submit制御(DoubleClick制御あり) function do_Submit_Clk2(mode) { if (doubleClick_flg == true) { window.setTimeout(function() { doubleClick_flg = false; }, 1); window.setTimeout(function() { doubleClick_flg = true; }, 1000); document.frm.mode.value = mode; document.frm.submit(); } else { return; false; } }
7/22 21:00-06:00