フジボウルの寺山です。
今回は、MySQLに携わっておきながらまだまだ理解が乏しいな感じだSQLインジェクションについて。
安全なSQLの呼び出し方の自分用にメモしたものです。
https://www.ipa.go.jp/files/000017320.pdf
ぜひ一読してみて下さい。
〇概要
SQLインジェクションの脆弱性がある場合、悪意あるリクエストにより、データベースの不正利用を招きます。
そのため、対策を必須なのでその前にまず、リテラルについて話ます。
〇リテラルとは
例えば、以下のSQLがあります。
SELECT a FROM atable WHERE name = "terayama"
SQL構成する要素には、キーワード、演算子、識別子、リテラルなどがある。
キーワード: SELECT FROM WHERE
演算子など: = <=
識別子: a atable
リテラル: "terayama"
リテラルとは、例えば社員番号で検索する際に以下のようなSQLで実施しますが、
SELECT a FROM atable WHERE id = '123'
ここでの'123'のような定数をリテラルと呼び、文字列としてのリテラルを文字列リテラルと呼び。他にも日時リテラルとかあります。
〇SQLインジェクションの原因
SQLをアプリケーションから利用する場合、SQLのリテラル部分をパラメータ化する事が多いですら、このパラメータ化された部分を展開する場合、文法的に正しく文を生成しないとリテラルの外にはみ出した状態になり、リテラルの後ろに続く文として解釈されます。これがSQLインジェクションです。
例えば以下の一文があります。$id部分は変数で外部から与えられるものとします。
$q = "SELECT a FROM atable WHERE id = '$id'"
ここで$idに与えられるものが数字だけなら問題ないですが、例えば以下のようになる場合があります。
SELECT a FROM atable WHERE id = '';DELETE FROM atable--'
$idに';DELETE FROM atable--が与えられた場合です。この場合、データベースの内容が全て消されてしまいます。
--以降のものはコメントとして無視されます。これがSQLインジェクションの脆弱性です。
〇対策
パラメータを正しくリテラルとして展開することが必要です。
・文字列リテラルは、エスケープすべき文字をエスケープする。
・数値リテラルは、数値以外の文字を混入しないこと。
今回はここまで次回対策の続きといえるプレスホルダーについてまとめます。