構築、実装、運用、etc…。
どの場面においてもセキュリティは欠かせないものですが、今回は実装時に行うセキュリティ対策についてまとめていこうと思う。
とは言え、場合によって対策しなければならないものはたくさんあるので今回は、Webページなどで起こる、
- SQLインジェクション
- XSS
- CSRF
- セッションハイジャック
の4つを見ていこうと思う。
SQLインジェクション
SQL文を入力し、データベースから不正に情報を流出させるもの。
情報漏洩だけでなく削除や改ざんの恐れなどもある。
$query = "SELECT * FROM user WHERE id = '$user_id'";
という脆弱性のあるプログラムがあったとして、$user_idに対し
' or 'A' = 'A
という文を入れるとする。
WHERE文の前半部分で通らずとも'A' = 'A'が通ってしまうので実質
SELECT * FROM user;
というSQL文を実行したのと同じ結果となってしまう。
対策方法
- プレースホルダを使用する
- エスケープ処理を行う
ことで対策することができる。
例としてプレースホルダを使用した場合
$query = "SELECT * FROM user WHERE id = ?";
execute($user_id);
こういったプログラムを書けばあくまで値として文を入れるので不正なSQL文を実行しないようになる。
XSS(クロスサイト・スクリプティング)
ウェブアプリなどで、スクリプトを埋め込むことができる脆弱性を悪用し、利用者のブラウザ上で不正なスクリプトが実行され、情報漏洩などを起こす。
<div>
検索結果:<?php echo $keyword;?>
</div>
というプログラムで、$keywordに対し、
<font color="red">
などを入れると検索結果として出てきたものより後が全て赤文字で表示されてしまう。
入れる文によってはアラートを発生させたり、別ページに飛ばしたりと色々できてしまう。
対策
- HTML文の入力を許可しない
- 文字コードを指定する
ことで対策できる。
例としてHTML文の入力を許可しない(一部の文字を変換させる)もので、
<div>
検索結果: <?php echo htmlspecialchars($keyword,ENT_QUOTES);?>
</div>
というようなプログラムで先ほどのHTML文を入れたとしても「<」などの文字が「<」などといった文字に変換され、表示自体に問題はなく、かつセキュリティ対策にもなる。
CSRF(クロスサイト・リクエスト・フォージェリ)
Webアプリにログインした状態を維持したまま、悪意のあるURLをクリックするなどして、利用者の意図しないリクエストを実行してしまい、設定を変更されたり強制的に投稿されたりする。
対策方法
指定のフォームを利用して投稿しているかどうか確認(トークンを発行し正しいかどうか検証)することで対策できる。
トークンの発行時
$csrf_token = get_csrf_token();
$_SESSION['csrf_token'] = $csrf_token;
情報を渡す時
<form action="~~" method="post">
<input type="text" name="text">
<input type="hidden" name="scrf_token" value="<?php $csrf_token?>">
<input type="submit" name="comment" value="投稿">
</form>
リクエスト受け取り時
if($_POST['scrf_token']!=$_SESSION['csrf_token']){exit();}
セッションハイジャック
推測・盗用・固定化などがある。
一例として推測の場合を見てみる。
セッションIDの生成規則を割り出して有効なセッションIDを推測し利用者になりすます。
対策
- セッションIDを推測困難なものにする
- ログイン成功後、新しいセッションを開始させる
まとめ
自分のしたいことに対してどんな脆弱性が発生するかを考え、その対策をとっていくことが必要になってきます。
少しの油断がセキュリティに穴を開けるので注意しないといけないですね。