non-security.phpをコピーして、
セキュリティ対策済みの security.phpファイルをつくってみよう。
クロスサイト・スクリプティング対策
security.php (一部抜粋)
<?php foreach($results as $result): ?>
<section class='card my-4'>
<div class='card-header'>
<h5><?php echo htmlspecialchars($result["title"],ENT_QUOTES,"UTF-8") ?></h5>
</div>
<div class='card-body'>
<p class='card-text'>
<?php echo htmlspecialchars($result["body"],ENT_QUOTES,"UTF-8") ?>
</p>
</div>
<div class='card-footer'>
</div>
</section>
<?php endforeach; ?>
CSRF対策
security.php (一部抜粋)
<?php
//セッションの開始
session_start();
// MySQLサーバ接続に必要な値を変数に代入
$userName = 'root';
$password = '';
// PDO のインスタンスを生成して、MySQLサーバに接続
$dbh = new PDO('mysql:host=localhost;dbname=bbs;charset=UTF8;', $userName, $password);
$title = $_POST['title'];
$body = $_POST['body'];
//CSRFトークン確認
//echo "session:".$_SESSION["csrfToken"]."<br>";
//echo "post:".$_POST["csrfToken"]."<br>";
if(isset($title) && isset($body)){
// CSRF対策
if($_POST["csrfToken"] !== $_SESSION["csrfToken"]){
echo "エラー:不正なリクエストです!";
return;
}
try{
$sql = 'INSERT INTO posts(title, body) VALUES("'. $title .'","'. $body .'");';
$stmt = $dbh->query($sql);
}catch(PDOException $e){
print($e->getMessage());
}
}
// CSRFトークン生成
$csrfToken = md5(uniqid(rand()));
$_SESSION["csrfToken"] = $csrfToken;
//CSRFトークン確認
//echo "session:".$_SESSION["csrfToken"]."<br>";
//echo "post:".$_POST["csrfToken"]."<br>";
// ここにMySQLを使ったなんらかの処理を書く
$sql = 'SELECT * FROM posts';
$stmt = $dbh->query($sql);
SQLインジェクション対策
security.php (一部抜粋)
try{
//$sql = 'INSERT INTO posts(title, body) VALUES("'. $title .'","'. $body .'");';
$sql = 'INSERT INTO posts(title, body) VALUES(:title, :body)';
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':title', $title, PDO::PARAM_STR);
$stmt->bindValue(':body', $body, PDO::PARAM_STR);
$stmt->execute();
}catch(PDOException $e){
print($e->getMessage());
}