LoginSignup
19
22

More than 5 years have passed since last update.

PHPでのセキュリティ(のメモ)

Last updated at Posted at 2018-01-10

(1) SQLインジェクション対策

SQL は prepare() を使って記述する。
ここで、変数は「?」を使う。「.」等で変数を接続してはいけない。

$user_id = "1234";
$kind = "test";
$sql = "SELECT id, data FROM table_name WHERE id=? AND kind=?";
$stmt = $pdo->prepare($sql);
$stmt->bindParam( 1, $user_id, PDO::PARAM_STR);  // 1つめの ? に 1234
$stmt->bindParam( 2, $kind, PDO::PARAM_STR);     // 2つめの ? に test
$stmt->execute();

(2) XSS対策

変数を画面に表示する場合は htmlspecialchars() を使う。

echo '<h1>idは'.htmlspecialchars($user_id).'です。</h1>';

(3) スクリプトインジェクション対策

ユーザーが画面から入力する文字列などは、HTMLタグや PHPタグを取り除くと安心。

$comment = strip_tags($_POST["comment"])

(4) CSRF対策

ログイン後に、session_regenerate_id を実行する。

session_regenerate_id(true);

ログアウト後に、session_destroy を実行する。

// セッションクリア
session_destroy();

(5) CSRF対策 その2

遷移元画面でユーザーが情報を選択し、OKボタンをクリックして、
遷移先画面でSQLでデータを更新(INSERT,UPDATE、DELETE)する。
選択情報は、GETデータで選択内容を引き継ぐ。
という場合、ユーザがログインセッションを保持している状態で、悪意のあるページが遷移先画面のURLをたたかせると意図しないSQLが発行される。
(ぼくはまちちゃん! 的な問題)
このため、遷移元画面から遷移先画面へはトークンを連携するなどして、正しい遷移元である確認をする。

遷移元

// ランダムな8桁の数字でトークンを作る
$token = random_int( 10000000, 99999999 );
// セッションにトークンを入れる
$_SESSION["TOKEN"] = $token;

// URLにもトークンを入れる
echo '<a href="next.php?token='.$token.'">次のページ</a>';

遷移先

// セッションとURLのトークンが一致しなかったら処理しない
if( $_SESSION["TOKEN"] != $_GET["token"] ) {
  die("トークンが一致しません。");
}

(6) クリックジャッキング対策

.htaccessファイルに下記の命令を記述する。

Header set X-FRAME-OPTIONS "DENY"

または、PHPでHTMLを書く前に、header()をコールする。

<?php
  // クリックジャッキング対策
  header('X-FRAME-OPTIONS: DENY');
?>
<!doctype html>
<html>
…

クリックジャッキング対策ができているか確認。
下記のような感じで、適当なファイル(hoge.html)を作る。
「http://…/index.php」の部分にテストしたいURLを入れる。
なにもしていないと画面が表示されるが、クリックジャッキング対策をすると、空白になる。

<html>
  <iframe src="http://…/index.php" width="800" height="1000">
  </iframe>
</html>
19
22
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
22