生SQLを書くとき、気をつけることは何ですか。
変数を文字列連結でSQLに埋め込むと、そこが SQL インジェクションの入口になるからです。普段 Eloquent が守ってくれている部分なので、生SQLに落ちた箇所だけ穴が開きます。
面接官が見ているのはセキュリティ意識の補強。
これは「Eloquent を使わず Query Builder や生SQLを選ぶのが妥当なのはどれですか。」への追撃質問です。
よくある答えと、面談でどう見られるか
- 値は必ずバインドパラメータで渡し、文字列連結で埋め込まない
その通りです。テーブル名や列名はバインドできないので、そこは許可リストで縛ります。 - 入力値を addslashes() でエスケープしてから連結する
addslashes は SQL インジェクション対策として不十分です。バインドを使ってください。 - 生SQLでは Laravel が自動でエスケープしてくれる
してくれません。Eloquent や Query Builder が守ってくれていたものが、生SQLに落ちた瞬間に自分の責任になります。 - SELECT なら安全なので対策は不要
SELECT でも情報漏洩や UNION による抜き取りが起きます。
面接官は何を見ているか
- バインドパラメータを使うと言えた
- 変数を文字列連結しないと言えた
- Eloquent が普段守ってくれていたものだと認識できた
模範解答
値は必ずバインドパラメータで渡します。DB::select('... where id = ?', [$id]) の形です。変数を文字列連結でSQLに埋め込むと、そこがSQLインジェクションの入口になります。普段 Eloquent や Query Builder を使っていると自動でエスケープされるので意識しませんが、生SQLに落ちた瞬間に自分の責任になります。なお、テーブル名や列名はバインドできないので、そこは許可リストで縛ります。