マスアサインメント脆弱性は、どういうコードで起きますか。
リクエストの中身をそのままモデルに渡すと起きます。攻撃者は入力欄が無くても is_admin=1 を付け足して送信できるからです。防御は fillable と、渡す値を明示的に選ぶことです。
面接官が見ているのは$fillable が何のためにあるかを理解しているか。
よくある答えと、面談でどう見られるか
- User::create($request->all()) のように、リクエストの中身をそのまま保存している
その通りです。画面に無い is_admin などを勝手に足して送られます。 - 大量のレコードを一度に insert している
「マス」は件数ではなく「まとめて代入する」の意味です。 - 同じ変数に何度も代入している
PHP の変数の話ではありません。モデルへの一括代入の話です。 - パスワードをハッシュ化せずに保存している
それも問題ですが別の脆弱性です。
模範解答
リクエストの中身をそのままモデルに渡す実装が原因です。
User::create($request->all()); // 危険
攻撃者はフォームに入力欄が無くても、is_admin=1 を勝手に付け足して送信できます。HTTPリクエストは自由に組み立てられるからです。
防御は2つ。モデルの $fillable に代入を許す列だけを列挙すること、または $request->all() ではなく $request->validated() を渡し、検証を通った項目だけに絞ることです。