現在私が参画しているプロジェクトでは、システムの脆弱性対応を行っています。
外部の診断ツールを利用して、システムに対して検査をかけ、診断結果に応じてプログラムやSQLの改善を行うというものです。
今回はその対応の中で出てきたSQLインジェクションについて紹介していきたいと思います。

新入社員研修の時に教えてもらった記憶はありますが、実際に仕事でこの事象に対応するのは今回が初めてでした。
多くのwebシステムでは、ユーザーが画面にて入力を行い、その入力値をプログラムがパラメータとして受け取り、SQLの実行を行うことでデータの検索、登録、更新を行っているかと思います。
SQLインジェクションはユーザーが悪意を持った文字列を入力することにより、本来想定していないデータの取得、改竄を行う事象です。例えば社員IDを画面で入力して、社員情報を検索する機能があった場合、

 select * from T_Shain where shain_id = ‘画面で入力した社員ID’

上記のようなSQLが用意されているかと思います。
社員IDの入力欄にa’ or 1 = 1と入力すると、生成されるSQLは

 select * from T_Shain where shain_id = ‘a’ or 1 = 1

となってしまい、’a’以後にorで1 = 1の必ずtrueとなる条件が追加されてしまい、全件参照可能となってしまいます。
SQLインジェクションへの対策として最初に挙げられるのがプレースホルダーによるバインドです。
プレースホルダーとはSQLがパラメータを受け取るためにあらかじめ用意している領域のことで、プレースホルダーを用いると検索用のSQLは以下のようになります。
※言語やDBにより指定の仕方は様々なので、下記はあくまで一例です。

 select * from T_Shain where shain_id = ?

プレースホルダーを用いてバインドを行った場合、SQLは

 select * from T_Shain where shain_id = ’‘a’ or 1 = 1’

となり入力値はまとめて一つの文字列とみなされるので、悪意を持った文字列を入力してもSQL全体の構成に影響を与えることはありません。
プレースホルダーの使用 はSQLインジェクションの対策の中でも代表的なものですが、診断ツールによってはプレースホルダーの使用だけでは指摘が消えない場合があります。
私のプロジェクトでも何度もSQLの見直しを行っても指摘が解消されず、困った記憶があります。

次に有効な対策としてバリデーションの使用が挙げられます。
バリデーションはSQLに対して修正を行うのではなく、SQL実行前にプログラム側で入力値のチェックを行い、’や;といったSQLに影響を及ぼす文字列が含まれている場合はエラーで弾く仕組みのことです。
こちらの場合は不正な文字列が含まれていた時点で、SQLの実行自体が行われないのでより確実にSQLインジェクションを防げます。

SQLインジェクション以外の脆弱性に関する事象及びその対応内容についてはまた別の機会に紹介させていただきます。
それでは、 See you next time👉