SQL インジェクションとは何ですか。どう防ぎますか

入力を文字列としてつないだせいで、入力が SQL の文の一部として読まれてしまう穴、と答える問い。プレースホルダーと最小の権限で守ることを話します。

こう聞かれます

  • 「SQL インジェクションとは何ですか。どう防ぎますか」
  • 「検索の語を SQL の文字列につないで組み立てるコードがあります。何が問題ですか」
  • 「入力の ' を消せば防げますか」(守りの中心を分かっているかを確かめる形)

面接官が見ている点

  • 入力が「値」ではなく「SQL の文」として読まれてしまう、と仕組みで話せるか
  • 守りの中心に、プレースホルダーを使った書き方を挙げられるか
  • 記号を消すような手の守りに頼らないこと、権限を絞って被害を小さくすることまで言えるか

短い答え

  • SQL インジェクションは、入力を SQL の文字列につないだせいで、入力が値ではなく SQL の文の一部として読まれてしまう穴です。
  • 防ぎ方の中心は、プレースホルダーを使い、SQL の形と値を分けてデータベースに渡すことです。
  • 加えて、アプリが使うデータベースの利用者の権限を、要る操作だけに絞って被害を小さくします。

少し詳しい答え

なぜ起きるか

入力をつないで SQL を組み立てると、入力の中の ' が文字列の終わりとして読まれます。次のコードは、入力をつないだ結果を表示するだけの例です。

JavaScript

const v = "x' OR '1'='1";
const q = `name = '${v}'`;
console.log(q);
name = 'x' OR '1'='1'

入力のつもりの OR '1'='1' が、条件の一部になってしまいました。これで、本来は出ない行まで返る条件に変わります。

プレースホルダーで分ける

WHERE name = ? のように値の場所だけを空けた SQL を先に渡し、値はあとから別に渡します。データベースは値をいつも値として扱うので、どんな文字が入っても SQL の形は変わりません。多くの言語のデータベースの道具や ORM は、この書き方を用意しています。

ORM を使っていても、生の SQL に文字列をつなげば同じ穴ができます。並べ替えの列名のように値として渡せない所は、許す列名を一覧で決め、その中から選ぶようにします。

被害を小さくする

アプリのデータベースの利用者には、要る操作だけを許します。たとえば読むだけの機能から表を消せないようにしておけば、穴が残っても被害が広がりにくくなります。

作った物と結ぶなら、たとえば「検索の機能で、語をつないでいた SQL をプレースホルダーの書き方に直し、' を含む語でも検索が壊れないことを確かめた」のように話します。

よくある間違い

  • 「' を消せば防げる」と言う 記号を消す守りは漏れやすく、正しい入力まで壊します。プレースホルダーで値と SQL を分けます
  • 「ORM を使っているから起きない」と言う生の SQL に文字列をつなぐ所があれば起きます
  • 「入力欄で文字数を絞れば大丈夫」と言う要求は画面を通さずに送れます。守りはサーバーの SQL の組み立て方で行います

深掘りの問い

  • 「並べ替えの列を利用者に選ばせるには」列名は値として渡せないので、許す列名の一覧から選ぶ形にする、と答えます
  • 「プレースホルダーを使えば、入力の確かめは要りませんか」 SQL の穴は防げますが、長さや形の確かめは別の目的で要る、と答えます
  • 「穴があったとき、被害を小さくするには」 データベースの利用者の権限を絞る、エラーの中身を画面に出さない、と答えます

確認日 2026年10月23日

技術面接問題の一覧へ戻る