0 / 4
SQLインジェクション(SQL Injection)
Web画面に入力した値はAPIサーバー(バックエンド)に渡る。APIサーバーはその値でSQLクエリを作り、データベース(DB)に送る。クエリを文字列の連結で作ると、入力の中のSQL構文が値ではなくクエリの一部として読まれる。SQLインジェクションはこの点を突いてクエリの構造を変える攻撃である。
例:普通の名前を入力するとどう処理されるかを見る。上で別の入力も選べる。
1 / 4
Web画面:名前を入力
ユーザーがWeb画面の名前欄にaliceを入力する。普通の文字だけが入っている。
2 / 4
APIサーバー:クエリを作る
APIサーバー(バックエンド)が、Web画面から渡った入力値を固定のクエリ文の間に連結する。入力値は引用符の中に入る。
3 / 4
APIサーバー → DB:クエリを送る
APIサーバーは完成したクエリを1文でDBに送る。このとき、どこまでがクエリ文でどこからが入力値かはDBに伝えない。
4 / 4
DB:クエリを実行
DBがクエリを読む。引用符の中のaliceは値なので、名前がaliceの会員1人だけを探して返す。
1 / 4
Web画面:悪意のあるSQLを入力
攻撃者がWeb画面の名前欄に、名前の代わりに' OR '1'='1を入力する。引用符でクエリの名前の位置を閉じ、常に真になる条件を付け足す入力である。
2 / 4
APIサーバー:クエリを作る
APIサーバーはWeb画面から渡った入力が何かを確認せず、そのまま連結する。そのため、入力の中の引用符とOR条件がクエリ文の一部になる。
3 / 4
APIサーバー → DB:クエリを送る
APIサーバーがクエリをDBに送る。このクエリの条件はすでにname = '' OR '1'='1'になっていて、開発者の意図とは違う。
4 / 4
DB:クエリを実行
DBは付け足された条件までクエリとして読む。この条件の'1'='1'は常に真なので、名前に関係なく全会員が結果に出る。
1 / 4
Web画面:名前を入力
ユーザーがWeb画面の名前欄にaliceを入力する。入力はそのままAPIサーバーに渡る。
2 / 4
APIサーバー:ひな形を先に送る
APIサーバー(バックエンド)がクエリのひな形を先にDBに送る。値が入る位置は疑問符で空けておく。DBはこのひな形でクエリの構造を決める。
3 / 4
APIサーバー → DB:値を別に送る
次に入力値を別に送る。DBはこの値をひな形の疑問符の位置に、値としてだけ入れる。
4 / 4
DB:クエリを実行
DBはaliceを名前の値として比べ、会員1人を探す。正常な入力はバインドを使っても同じように処理される。
1 / 4
Web画面:悪意のあるSQLを入力
攻撃者がWeb画面の名前欄に' OR '1'='1を入力する。入力はそのままAPIサーバーに渡る。
2 / 4
APIサーバー:ひな形を先に送る
APIサーバー(バックエンド)がクエリのひな形を先にDBに送る。値が入る位置は疑問符で空けておく。DBはこのひな形でクエリの構造を決める。
3 / 4
APIサーバー → DB:値を別に送る
次に入力値を別に送る。入力に引用符やOR条件が入っていても、すでに決まった構造には割り込めない。
4 / 4
DB:クエリを実行
DBは入力全体' OR '1'='1を1つの文字列の値としてだけ比べる。名前がその文字列の会員はいないので、1人も見つからない。攻撃の試みは何も起こせない。