FlawOpen

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や明示的フィールド指定も同じ境界を作ります。

許可リストは設定可能な属性を制限しますが、変更権限は与えません。認証済み主体の範囲に限定し、操作を認可し、特権変更を別のサーバーフローにします。

確認する機密フィールド

モデル属性、ネストしたシリアライザー、更新エンドポイントを確認します。

よくある質問

prototype pollutionと同じですか?

別の弱点です。Mass Assignmentは作成・更新対象に意図しない属性を設定します。Prototype pollutionはプロトタイプのプロパティを変え、他オブジェクトの検索に影響することがあります。危険なマージが原因になり得ますが、Mass Assignmentも起きるかはプロパティの使い方次第です。prototype pollutionを参照。

GraphQLなら防げますか?

いいえ。GraphQL mutationも広い入力を受け付ける可能性があります。入力型を許可項目に絞り、resolverやサービスで認可します。

サーバー描画フォームは保護になりますか?

いいえ。表示フォームはHTTPクライアントの送信内容を制限しません。全項目を信頼できない入力として検証し、その操作で許可された項目だけ受け入れます。

参考資料

関連項目 Serverless の状態漏えい:ユーザーデータをリクエストごとに分離 PHP == と Magic Hash の比較 Rust の unsafe ブロックはメモリ安全なのか? strncpy() は strcpy() より安全ですか? CWE と CVE:何が違うのか