前提
プログラミング初学者(2~3ヶ月)が学んだ内容です。
実際の現場で通用しないことや間違った内容が含まれている可能性があります。
間違っている部分や浅い部分については追記やご指摘いただけると幸いです。
データベースシステムを不正に操作する攻撃(SQLインジェクション)
アプリケーションの不備を利用して、データベースシステムを不正に操作されることがあります。
このような攻撃方法をSQLインジェクションといいます。
SQLインジェクションの前にSQLとは何かについて先に解説します。
SQLとは?
SQLはStructured Query Languageの略でデータベース言語です。
データベース言語とはデータベースとやり取りする時に使われる言語です。
例えば、
日本人に話すときは日本語を、ドイツ人に話すときはドイツ語をといったように、
データベースに何らかの処理をしてほしいときはデータベース語つまりSQLを使って指示して下さい。
ということです。
具体的な処理としては、データベースにデータを挿入したり、検索したりする時に使われます。
数万、数百万以上のデータであっても、SQLを使うことで効率的に作業することが可能になります。
SQLインジェクションとは?
「Webページのテキスト入力欄」や「URL」などにSQL文の断片を埋め込むことで、データベースを改ざんしたり、不正に情報を入手する手法
入力フォームから送信した値によって、アプリケーションが本来想定しないSQL文を実行させ、攻撃を行います。
例えば、フォームを送信する時に文章の中にユーザーの権限を変更するようなSQL文を仕込んで送信します。
すると、サーバーサイドでそのSQL文が実行され、ユーザー権限が変更されてしまうような処理が行われます。
Twitterでいうとツイートのフォーム部分にSQL文の断片を入力してデータベース上にある全てのツイートを情報を削除するといったようなことをすることです。(もちろんTwitterはきちんと対策がされています。)
SQLインジェクションの対策
上記のようなSQLインジェクションの脆弱性を防ぐために、
SQL文が実行される際のプログラムの処理の流れを利用して、SQL文が変更されることを防ぐ方法が2つあります。
**対策①意味のある特殊文字のエスケープ
SQLにおいて意味を持つ特殊文字のエスケープによって対策できます。
SQL文中では「'」が文字列の終端を意味します。
例えば、ユーザーIDとパスワードを入力して一致するとログインできる機能を考えてみます。
ログイン認証のSQLを以下とします。
SELECT * FROM users WHERE user_id='$uid' AND password='$pwd'
ここにログインのために以下のようなユーザーとパスワードを入力します。
$uid nako
$pwd ' OR 'A'='A
するとSQL文が以下のようになります。
SELECT * FROM users WHERE user_id='nako' AND password='' OR 'A'='A'
元々はusersテーブルのuser_idとpasswordが一致した時にログインするという記述でした。
しかし記述内容を見てみると、
password='' OR 'A'='A'
となっており、password=''
か'A'='A'
のどちらかが成立すればTrue、つまりログインできてしまうということになります。
もちろん'A'='A'はTrueなので、passwordがわかっていなくてもuser_idがnakoということさえ分かっていれば、アカウントにログインができてしまうということです。
細かく記述を見ていくと、ORの前の「'」の記述の終端を示しています。
その後のORから先が新たな記述となり、'A'='A'という記述になっています。
この場合、「'」のようなSQLにおいて意味を持つ特殊文字をエスケープすることで対策が可能です。
**対策②より厳格なSQL文の生成**
ユーザーからの値をSQLへ反映する前に、SQL文の構造を確定する仕組みをとることで、より厳格に対策できます。
SQL文確定後にユーザーからの値を入れて実行するため、ユーザーの入力値によってSQL分が変更されることはありません。
この実装にはプレースホルダという記述が使われます。
プレースホルダ
プレースホルダはユーザーの値が入力されるまでの一時的な仮引数のようなもの
予め確定したSQLにおいて、可変の値が入力される箇所に配置します。
プレースホルダを使って指定しておくと、その部分は値として処理されます。
不正な値が入力されても、SQL命令に関わるような特殊文字は無効化され、SQLとして実行されなくなります。
まとめ
SQLとはデータベースと遣り取りをする時に使われる言語のこと
SQLインジェクションはSQLをフォーム欄やURLなどに埋め込むことでデータベースの改ざん(変更・削除)を行う行為。SQLインジェクションの対策は
①SQLで意味のある特殊文字のエスケープ
②プレースホルダを用いて入力されるものを全て値に限定し、SQL文の構造を確定することで、SQL命令にかかわる特殊文字を無効化できる。