| この記事の要点 |
|---|
|
マスアサインメント保護
Laravel の User::create($request->all()) のように配列を一括代入する操作(マスアサインメント)は、攻撃者が任意のフィールドを送り込める脆弱性があります。$fillable / $guarded でこれを制御します。
$fillable(ホワイトリスト・推奨)
class User extends Model
{
protected $fillable = [
'name',
'email',
'phone',
];
// role や is_admin は含まれない → 一括代入できない
}
// 使用
User::create([
'name' => 'Alice',
'email' => 'alice@example.com',
'role' => 'admin', // ← 無視される (fillable にないので)
]);
User::create($request->all());
// → name, email, phone のみセットされる、他は無視
$guarded(ブラックリスト)
class User extends Model
{
// 'id', 'role' は一括代入禁止
protected $guarded = ['id', 'role', 'is_admin'];
}
// 空配列で全許可 (危険、テスト用)
protected $guarded = [];
// ガード解除 (デバッグ用、本番禁止)
Model::unguard();
$fillable と $guarded はどちらか一方
$fillable推奨: 許可するものを明示するほうが安全$guarded: 多くを許可する場合、禁止するものだけ列挙- 両方使うと
$fillableが優先
マスアサインメントが効くメソッド・効かないメソッド
| メソッド | マスアサインメント保護 |
|---|---|
Model::create($attrs) | ○ |
$model->fill($attrs) | ○ |
$model->update($attrs) | ○ |
$model->save() | ×(直接代入は OK) |
$model->forceFill($attrs) | ×(強制代入) |
Model::forceCreate($attrs) | × |
個別代入 $model->name = ... | × |
// 個別代入は OK
$user = new User();
$user->name = "Alice";
$user->role = "admin"; // ← fillable に関係なくセットできる
$user->save();
// forceFill / forceCreate は意図的に保護をバイパス
$user = User::forceCreate([
'name' => 'Admin',
'role' => 'admin',
'is_admin' => true
]);
$hidden(JSON シリアライゼーション)
toArray() / toJson() 時に含めない属性:
class User extends Model
{
protected $hidden = [
'password',
'remember_token',
'api_secret',
];
}
// 使用
$user = User::find(1);
return $user->toJson();
// → {"id":1, "name":"Alice", "email":"..."}
// password は含まれない
return $user; // 自動的に JSON 化される (Resource Controller)
// → 同上、password 非表示
$visible(逆: 表示するもののホワイトリスト)
class User extends Model
{
protected $visible = ['id', 'name', 'email'];
// → これら以外は全て隠す
}
// $hidden と $visible は併用可、$hidden が優先
動的に変更
// 一時的に表示 / 非表示
$user = User::find(1);
$user->makeVisible('password'); // password を表示
$user->makeHidden(['name', 'email']); // 一時的に隠す
return $user->toJson();
その他の関連プロパティ
$casts(型変換)
class User extends Model
{
protected $casts = [
'is_admin' => 'boolean',
'options' => 'array', // JSON カラム → 配列に
'birthday' => 'date',
'last_login_at' => 'datetime',
'price' => 'decimal:2',
];
}
// 利用
$user->is_admin // → bool
$user->options // → array (DB は JSON 文字列)
$user->birthday // → Carbon インスタンス
$dates(廃止予定、$casts に統合)
// 古い書き方 (Laravel 6 以前)
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
// 新しい書き方 (Laravel 7+)
protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
$appends(カスタム属性をシリアライズに含める)
class User extends Model
{
protected $appends = ['full_name'];
public function getFullNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
}
// toJson() の結果
// {
// "id": 1,
// "first_name": "Alice",
// "last_name": "Smith",
// "full_name": "Alice Smith" ← appends で追加
// }
標準的なモデル例
class User extends Authenticatable
{
use HasFactory, Notifiable;
// 一括代入を許可するフィールド
protected $fillable = [
'name',
'email',
'password',
];
// シリアライゼーションから除外
protected $hidden = [
'password',
'remember_token',
];
// 型変換
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed', // 自動でハッシュ化
];
// 追加属性
protected $appends = ['avatar_url'];
public function getAvatarUrlAttribute()
{
return $this->avatar
? Storage::url($this->avatar)
: asset('img/default-avatar.png');
}
}
セキュリティ上の注意
- $fillable の指定なしは MassAssignmentException 発生 (Laravel 5.5+)
- $guarded = [] は危険、絶対使わない(本番では)
- パスワード等の機密情報は必ず $hidden に
- API レスポンス用には API Resources を使うほうが柔軟
API Resources(より柔軟)
// 専用のリソースクラス
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->toIso8601String(),
// フロント側に必要な情報だけ厳選
];
}
}
// コントローラから
return new UserResource($user);
return UserResource::collection($users);
関連記事
子ページ
子ページはありません
同階層のページ
- モデルの作成
- $fillable $guarded $hiddenの説明
- テーブルの紐づけ
- 主キーの指定とインクリメント
- タイムスタンプ
- モデルでselect
- モデルでinsert
- モデルでupdate
- 現在値に加算する方法
- created_at/updated_atの別名指定
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09