初めまして。
現在PHPを勉強していて、クイズサイトを作成しています。
問題の編集画面にて、CSRFの対策を取ろうと思っているのですがうまくいきません。
PHP
1<?php 2 3session_start(); 4 5//変数宣言 6$num = $_GET['num']; 7$msg = ''; 8 9//セッションがセットされていない場合の処理 10if(!isset($_SESSION['NAME'])) { 11 12 header("Location: Login.php"); 13 exit(); 14 15} 16 17//管理者権限以外がページにアクセスした場合の処理 18if($_SESSION['kengen'] != 'kanri') { 19 20 header("Location: main.php"); 21 exit(); 22 23} 24 25//GETで受け取った値が不正だった場合の処理 26if(!preg_match("/^[0-9]+$/", $num)) { 27 28 header("Location: error.php"); 29 exit(); 30 31} 32 33 //GETで受け取ったNumのデータを引っ張る 34 try{ 35 36 //データベースから問題を引っ張る 37 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 38 $stmt = $DB->query("SELECT * FROM question WHERE num=".$num); 39 $row = $stmt->fetch(PDO::FETCH_ASSOC); 40 41 } catch(PDOException $e) { 42 43 $err_msg = 'データベースエラー'; 44 45 } 46 47 //更新機能 48 if(isset($_POST['update'])) { 49 50 //token発行 51 $token = sha1(uniqid(mt_rand(), true)); 52 $_SESSION['token'] = $token; 53 54 //CSRF対策 55 if($_SESSION['token'] != $_POST['token']) { 56 57 header("Location: error.php"); 58 exit(); 59 60 } 61 62 $title = $_POST['title']; 63 $content = $_POST['content']; 64 $question1 = $_POST['question1']; 65 $question2 = $_POST['question2']; 66 $question3 = $_POST['question3']; 67 $answer = $_POST['answer']; 68 69 70 if(!empty($title)) { 71 72 try{ 73 74 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 75 $stmt = $DB->prepare("UPDATE question set title = :title WHERE num =".$num); 76 $stmt->bindParam(':title', $title, PDO::PARAM_STR); 77 $stmt->execute(); 78 79 } catch(PDOException $e) { 80 81 $err_msg = 'データベースエラー'; 82 83 } 84 85 } 86 87 if(!empty($content)) { 88 89 try{ 90 91 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 92 $stmt = $DB->prepare("UPDATE question set content = :content WHERE num =".$num); 93 $stmt->bindParam(':content', $content, PDO::PARAM_STR); 94 $stmt->execute(); 95 96 } catch(PDOException $e) { 97 98 $err_msg = 'データベースエラー'; 99 100 } 101 102 } 103 104 if(!empty($question1)) { 105 106 try{ 107 108 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 109 $stmt = $DB->prepare("UPDATE question set question1 = :question1 WHERE num =".$num); 110 $stmt->bindParam(':question1', $question1, PDO::PARAM_STR); 111 $stmt->execute(); 112 113 } catch(PDOException $e) { 114 115 $err_msg = 'データベースエラー'; 116 117 } 118 119 } 120 121 if(!empty($question2)) { 122 123 try{ 124 125 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 126 $stmt = $DB->prepare("UPDATE question set question2 = :question2 WHERE num =".$num); 127 $stmt->bindParam(':question2', $question2, PDO::PARAM_STR); 128 $stmt->execute(); 129 130 } catch(PDOException $e) { 131 132 $err_msg = 'データベースエラー'; 133 134 } 135 136 } 137 138 if(!empty($question3)) { 139 140 try{ 141 142 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 143 $stmt = $DB->prepare("UPDATE question set question3 = :question3 WHERE num =".$num); 144 $stmt->bindParam(':question3', $question3, PDO::PARAM_STR); 145 $stmt->execute(); 146 147 } catch(PDOException $e) { 148 149 $err_msg = 'データベースエラー'; 150 151 } 152 153 } 154 155 if(!empty($answer)) { 156 157 try{ 158 159 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 160 $stmt = $DB->prepare("UPDATE question set answer = :answer WHERE num =".$num); 161 $stmt->bindParam(':answer', $answer, PDO::PARAM_STR); 162 $stmt->execute(); 163 164 } catch(PDOException $e) { 165 166 $err_msg = 'データベースエラー'; 167 168 } 169 170 } 171 172 173 $msg = '更新しました'; 174 175 } 176 177 178 try{ 179 180 //データベースから問題を引っ張る 181 $DB = new PDO('mysql:host=localhost;dbname=question;charset=utf8','root',''); 182 $stmt = $DB->query("SELECT * FROM question WHERE num=".$num); 183 $row = $stmt->fetch(PDO::FETCH_ASSOC); 184 185 } catch(PDOException $e) { 186 187 $err_msg = 'データベースエラー'; 188 189 } 190 191 192 193 194 195 196?> 197 198 199 200<!DOCTYPE html> 201<html> 202<head> 203 <title>問題編集</title> 204</head> 205<body> 206 <h3>問題編集</h3> 207 <p><?php echo $msg; ?></p> 208 <?php var_dump($_SESSION['token']); ?> 209 <form method="POST" action=""> 210 タイトル:<input type="text" name="title" value="" placeholder="<?php echo htmlspecialchars($row['title'], ENT_QUOTES); ?>"> 211 <br> 212 クイズ内容:<input type="text" name="content" value="" placeholder="<?php echo htmlspecialchars($row['content'], ENT_QUOTES); ?>"> 213 <br> 214 質問1:<input type="text" name="question1" value="" placeholder="<?php echo htmlspecialchars($row['question1'], ENT_QUOTES); ?>"> 215 <br> 216 質問2:<input type="text" name="question2" value="" placeholder="<?php echo htmlspecialchars($row['question2'], ENT_QUOTES); ?>"> 217 <br> 218 質問3:<input type="text" name="question3" value="" placeholder="<?php echo htmlspecialchars($row['question3'], ENT_QUOTES); ?>"> 219 <br> 220 回答:<input type="text" name="answer" value="" placeholder="<?php echo htmlspecialchars($row['answer'], ENT_QUOTES); ?>"> 221 <br> 222 <input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>"> 223 <input type="submit" name="update" value="変更"> 224 </form> 225 <a href="main.php">戻る</a> 226</body> 227</html>
問題箇所としては、//更新処理 の頭です。
現状、token自体は合っていると思うのですが変更ボタンを押下するとエラーページに遷移してしまいます。
宜しければご教示願います。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/02/04 03:30 編集
2018/02/04 10:54
退会済みユーザー
2018/02/04 11:20 編集
2018/02/04 12:56