flawopen.com/Mass Assignment/解説
Mass Assignment:リスクと安全なフィールド許可リスト
CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributesリファレンス
要点
モデルを利用者用の欄とスタッフ専用の操作欄がある用紙だと考えてください。リクエスト全体をバインドすると、顧客が所有者、承認、ロールまで設定できます。編集項目はサーバーで定義し、レコードと操作を別々に認可します。
VULNERABLE
# Rails: request keys reach model attributes User.new(params[:user]) // Node / Mongoose: request object used as update await User.findByIdAndUpdate(id, req.body); // Express + Sequelize: request object used as create values await User.create(req.body); # Django: request keys passed as model fields User.objects.create(**request.POST.dict())
FIXED
# Rails — permit only user-editable fields attrs = params.require(:user).permit(:name, :email) user = User.new(attrs) // Node — construct an allowlisted update const { name, email } = req.body; await User.findByIdAndUpdate(id, { name, email }); # Django — explicit ModelForm fields class UserForm(ModelForm): class Meta: model = User fields = ["name", "email"] // .NET — bind a DTO, then map explicitly user.Name = input.Name; user.Email = input.Email;
サーバー側の許可リストが重要な理由
「role以外はすべて許可」という拒否リストは、新しい機密フィールドの追加時に更新されないと失敗します。許可リストなら明示するまで新フィールドを編集できません。Rails Strong Parametersは一括割り当て時に未許可属性を拒否しますが、コントローラーは操作に必要な項目だけ許可します。DTOや明示的フィールド指定も同じ境界を作ります。
許可リストは設定可能な属性を制限しますが、変更権限は与えません。認証済み主体の範囲に限定し、操作を認可し、特権変更を別のサーバーフローにします。
確認する機密フィールド
モデル属性、ネストしたシリアライザー、更新エンドポイントを確認します。
- ✓所有者・テナントのキー — user_id、account_id、tenant_id。サーバーで所有権を確認し、クライアント指定を信頼しません。
- ✓ロール、権限、状態 — role、is_admin、email_verified、status。認可されたサーバー手順でのみ変更します。
- ✓金銭値とネスト/システム項目 — 残高、割引、クレジット、関連、タイムスタンプ、IDは業務ルールや更新範囲に影響します。各項目を意図的に許可・検証します。
よくある質問
prototype pollutionと同じですか?
別の弱点です。Mass Assignmentは作成・更新対象に意図しない属性を設定します。Prototype pollutionはプロトタイプのプロパティを変え、他オブジェクトの検索に影響することがあります。危険なマージが原因になり得ますが、Mass Assignmentも起きるかはプロパティの使い方次第です。prototype pollutionを参照。
GraphQLなら防げますか?
いいえ。GraphQL mutationも広い入力を受け付ける可能性があります。入力型を許可項目に絞り、resolverやサービスで認可します。
サーバー描画フォームは保護になりますか?
いいえ。表示フォームはHTTPクライアントの送信内容を制限しません。全項目を信頼できない入力として検証し、その操作で許可された項目だけ受け入れます。