最近フレームワークを使っていない生PHPサイトのPHPバージョンアップや、クラウドソーシングで得たwebデザイン業務の元ソースが生PHPで書かれていたりなど、意外とこの昨今でも生PHPを見る機会があります。
そこで今回は生PHPを書く際に絶対に気をつけたいセキュリティについて3つまとめたいと思います。
①SQLインジェクション対策
もうこれは、本当に対策して欲しい。未対策サイトがあったらもう関わりたくないです。むしろ、元々の業務を差し置いてでも、対策したいと思います。
そこまでいうSQLインジェクションとは、例えば、ログイン画面のあるサイトで対策されていないとすると、ユーザ情報を抜き出したり、はたまたDBの中身を削除することができます。
そんなことできるわけねぇだろという方、こんなソースに心当たりはありませんか?
$query = "SELECT * FROM users
WHERE id = '$id' and pass = '$pass'";
Code language: PHP (php)
このソースの何がダメかというと、例えば $idと$passに ’ or ‘1 = 1 が入るとどうなるでしょうか?
$query = "SELECT * FROM users
WHERE id = '' or '1 = 1' and pass = '' or '1 = 1'";
Code language: PHP (php)
これが実行されるとどうでしょうか?
まずwhere句の前半を確認しましょう
id = ” or ‘1 = 1’ これが実行されると、id の中身がないor 1=1 になります。1=1はtrueなので、where句の前半はtrueで通ります。
続いて、where句の後半を確認しましょう
pass = ” or ‘1 = 1’ 前半と同じ解釈ができるので、trueが通ります。
前半と後半をまとめると
$query = "SELECT * FROM users
WHERE 1=1 and 1=1";
Code language: PHP (php)
になり、usersテーブルの中身が引き出されてしまいます。あとは、limit や offsetを使って、1個ずつユーザ情報を取り出して、ログインすることもできますし、コメント(–)を使って、delete文を仕込んだり、好きなだけ悪さを働くことができます。
SQLインジェクションを試すことは日本の法律で違法になりますので、そういった勉強できるサイトを紹介しておきます。
ダンジョンを攻略しつつSQLインジェクションの脆弱性について学べるサイト「Lord of SQLInjection」
②CSRF(クロスサイトリクエストフォージェリ)対策
フレームワークを使ったことがあるならなんとなく聞いたことがあるかもしれません。LaravelならBladeでform使うときに@csrfが必要になってきますよね。
このCSRFというのはformのあるサイトで必須の対策なんですが、意図しないデータを受け取らないための対策です。
例えば、以下のようなソースがあるとします。
<form action="receive.php" method="POST">
~~省略~~
</form>
Code language: HTML, XML (xml)
当然ながらPOSTを受け取るreceive.phpが同じドメイン(今回は同じサーバのフォルダ内)にあると思います。このreceive.phpに全然関係ないサイトからPOSTが飛んできたらどうでしょうか?
<form action="https://攻撃対象ドメイン/receive.php" method="POST">
<input type="hoge" value="hoge">を使ってreceive.phpが意図しないデータを注入
</form>
Code language: HTML, XML (xml)
このようにしてバグを注入することができます。
どうやって対策するかというと、csrfトークンを生成します。
<?php
~~省略$_SESSION['csrfToken'] = "ランダムの文字列"
~~省略?>
<form action="receive.php" method="POST">
<input type="hidden" value="ランダムの文字列" name="csrfToken">
~~省略~~
</form>
Code language: HTML, XML (xml)
こうして、formにランダムの文字列を注入します。
受け手のreceive.phpは以下のように
<?php
~~省略$_SESSION['csrfToken'] === $_POST['csrfToken']){
echo "正常なform遷移です";
}else{
echo "csrfの疑いあり";
}
?>
Code language: HTML, XML (xml)
することで対策できます。
かつて、あの有名なmixiでcsrfによる攻撃を受け、たくさんのユーザが意味不明の同内容の投稿をしたことで話題になりました。
大量の「はまちちゃん」を生み出したCSRFの脆弱性とは?
③XSS(クロスサイトスクリプティング)対策
XSSは幅広い悪さがあるので、一番わかりやすいものだけご紹介します。
ユーザが入力したスクリプトが投稿されたページで実行されてしまう攻撃です。
先程のようなformに、input type=”text”がある場合、入力フォームに以下を打ち込まれと
<script>alert("XSS");</script>
Code language: HTML, XML (xml)
この内容を表示する確認画面や投稿一覧画面にて、XSSと記載されたアラート表示されてしまいます。そういう時は、以下を使いましょう
htmlspecialchars($_POST['入力内容'])
Code language: PHP (php)
htmlspecialchars関数を使って出力することで < や ” などがエスケープされて無害化の状態で出力されます。今回はゆるい内容でしたが、権限昇格などにつながる危険性があります。前回の記事も参考になると思います。
まとめ
あなたのサイトは対策できていたでしょうか?ちなみに普段利用しているサイトに脆弱性を発見した場合、サイト運営者に連絡するのもよいですが、IPAに問い合わせることで、報告者も運営者も安心して対応することができます。
キャクヨセへのお仕事依頼はこちらからよろしくお願いいたします!