エンジニアリング部システムソリューション課のひよっこエンジニアKと申します。わからないことをまとめたシリーズ第三弾です。 突然ですが皆さんは湘南乃風の睡蓮花をご存知ですか?この歌詞をまとめた歌詞サイトで、なんと徐々に文字のサイズが大きくなってしまうという現象が起きたことがありました。実はこの原因もSQLインジェクションの原因と同じなんです。今回はそんなおかしな現象から甚大な被害まで起こすSQLインジェクションの脆弱性と、その対策についてまとめてみようと思います。
SQLインジェクションってなに?
SQLインジェクションはインジェクションという脆弱性の中で有名なものの1つです。SQLインジェクションは、SQL(データベース)の呼び出しに不備がある場合に発生する脆弱性と『安全なWebアプリケーションの作り方』では紹介されています。この脆弱性が存在すると、データベース内のすべての情報が外部から盗まれてしまったり、データを改ざんされたりと甚大な影響を及ぼします。次の項目では、実際のインジェクション攻撃の仕組みを見てみましょう。
SQLインジェクション攻撃の仕組み
例えばあるサイトで、フォームに記入してIDを指定するとそのIDのデータだけ表示できるページがあったとします。SQL文はPHPで以下のように定義していたとします。
$sql = "select * from sample where id = ‘{$input}’"
例えばフォームの部分に1と記入したとき、実行されるSQL文は
select * from sample where id = ‘1’
となって、id=1のデータをすべて見ることができる、という感じです。
しかし、もしそのサイトがインジェクション脆弱性をもったサイトで、フォームの部分に1’ OR ‘1’ = ‘1と記入されたらどうなるでしょうか?この場合、データベースにくだされる命令は、「idが1のデータか、1=1がなりたつときのデータを選択する」になります。1=1は常に成り立つので、これですべてのデータを見れてしまうことになります。
図にまとめてみると以下のようになります。
①攻撃者が攻撃対象サイトの入力画面でSQL文を含む文字列を入力する
上記の例だと、1’ OR ‘1’ = ‘1’とフォームに記入する部分がこの過程に当たります。
②Webサイトは入力された値をもとにSQL文を生成し、データベースに指示を出す
上記の例で言うところの、「idが1のデータか、1=1がなりたつときのデータを選択する」とデータベースに命令がくだされる部分です。つまり、ここでSQL文で全件表示するようにデータベースに指示が出されています。
③(1)データの改ざん・削除や(2)データの漏洩が起こる
上記ではデータの漏洩が起こっていましたが、シングルクォーテーション以下に別のDelete文などのSQL文が挿入されてしまうと、データがすべて消えたり、勝手に編集されてしまったりします。
SQLインジェクション脆弱性対策は何をすれば良いのか?
攻撃の仕組みを見てみると、フォームで想定されている数字以外が入力されてしまっていることがわかります。また、シングルクォーテーションがそのままシングルクォーテーションとして処理されてしまっていることも問題です。つまり、想定している文字以外が入らないようにしておくことと、SQL文として処理する際意味を持つ記号をエスケープしてただの文字列として扱うようにしておくことが大事だということです。
①想定している文字しか入らないようにする
まず、複数のSQL文が入らないようにする方法として、PDOを使うという方法があります。しかし、PDOを使ったからといってすべての被害が完璧に防げるわけでは全くありません。例えば、上記に挙げた数字以外の文字を挿入されてしまう例なら、入力された文字が数字かどうか確かめ、そうでない文字が入力された場合はエラーにしてデータベースに接続させないなどの方法があります。
②意味を持つ記号をエスケープしてただの文字列として扱うようにしておく
①に加えて、一部の記号をエスケープしておくという対処も必要です。SQLインジェクションの場合は、PDOのプレースホルダを使ってSQL文を組み立てることによって、シングルクォーテーション等の意味を持つ記号をエスケープしてくれます。プレースホルダを利用すると、先程のSQL文は下記のようになります。
$sql = "select * from sample where id = ?"
?部分がプレースホルダになります。プレースホルダの部分に値を割り当てます。
実は冒頭に出てきた湘南乃風の睡蓮花の歌詞の例も、エスケープ処理をすれば正常に表示されるようになります。大きくなってしまった原因は、歌詞の<<Big Wave!!という箇所の<をエスケープ処理していなかったためでした。<<Bigの部分を<big>とブラウザ側に処理された結果、珍現象が起きたのでした。ちなみに、htmlのエスケープ処理をしたいときは、PHPのhtmlspecialchars関数を使うと便利です。
今回のまとめ
①SQLインジェクションは、SQL(データベース)の呼び出しに不備がある場合に発生する脆弱性
②SQLインジェクションの脆弱性を突いた攻撃をされると、データの改ざん・削除・データの漏洩など甚大な被害を受ける可能性がある
③SQLインジェクションの対策として、想定している文字しか入らないようにすることと、意味を持つ記号をエスケープしてただの文字列として扱うようにすることの2つが必要である
④SQLインジェクション対策としてPDOは有効
参考サイト:
うたまっぷ 珍現象!湘南乃風の睡蓮花の歌詞が大きくなるのはなぜ?【比較画像あり】
SQLインジェクションとは?Webサイトのセキュリティ対策を学ぼう
SQLインジェクション攻撃への対策|脆弱性を悪用する仕組みと具体例
参考図書:
『安全なWebアプリケーションの作り方(第2版)』(徳丸浩著) p.151-171