SQLインジェクション入門:仕組みと対策
SELECTとWHEREの読み方
この回でやること
どの列を取り出し、どの行に絞るのか。SELECTとWHEREの読み方と、条件が並んだときにANDとORがどの順で結ばれるかを確かめます。
- 読む 約 9 分
- 最後にクイズ 1 問
このレッスンで学ぶこと
SELECTはどの列を取り出すか、WHEREはどの行に絞るかを指すSQLの命令です。この回はこの2つを読めるようにし、条件がANDとORで複数並んだときにどの順で結ばれるかまで確かめます。
その読み方だと、返る行がまるごと入れ替わる場合があります。読み終えるころには、同じ1行のWHEREを見て、どの行が残るかを手で追えるようになります。
SELECTは取り出す列、WHEREは絞る行
SELECTはどの列を取り出すか、FROMはどの表から、WHEREはどの行に絞るかを指します。次の命令を読んでみます。
SQL クエリ
SELECT name, role FROM users WHERE name = 'tanaka'「users表から、nameがtanakaである行だけを選び、そのnameとroleを取り出せ」と読めます。WHEREが無ければ全員分の行が対象ですが、WHERE name = 'tanaka'が付くことで、条件に合う1行だけに絞られます。name = 'tanaka'は「name列の値がtanakaという文字列と等しい」という比較で、これが真になる行だけが残ります。
条件が並ぶとき、ANDが先に結ばれる
条件は1つとはかぎりません。両方が真であってほしいときはAND、どちらか一方でよいときはORでつなぎます。問題は、両方が混じったときにどう結ばれるかです。次を見てください。
SQL クエリ
SELECT name FROM users
WHERE role = 'admin' OR role = 'member' AND name = 'tanaka'ANDはORより先に結ばれます。だから後半がひとかたまりになり、role = 'admin' OR (role = 'member' AND name = 'tanaka')と読みます。adminの行は前半で真になって残り、tanakaの行は後半のかたまりが真になって残ります。o'brienはmemberですが名前が違うので、後半が偽になり残りません。返るのはadminとtanakaの2行です。
後半のかたまりがANDだからです。role = 'member'は真でもname = 'tanaka'が偽なので、かたまり全体が偽になります。adminが残ったのは前半のOR側で真になったからで、後半とは関係ありません。もし左から結んで(role = 'admin' OR role = 'member')AND name = 'tanaka'と読むと、今度はadminが落ちます。
ANDはORより強く結びます。A OR B AND Cは、位置に関係なくA OR (B AND C)です。この結ばれる順の強さが、後の回でログイン画面の通り方を左右します。名前の欄に条件を1つ混ぜただけでは、後ろに残った別の条件がANDで生き残ってしまうからです。
手を動かすなら、WHEREの条件をANDにしたりORにしたりして、返ってくる行がどう変わるかを見比べてください。1文字の違いで対象がまるごと入れ替わることが、目で分かります。