mass-assignment-anti-pattern

mass-assignment-anti-pattern

Security anti-pattern for mass assignment vulnerabilities (CWE-915). Use when generating or reviewing code that creates or updates objects from user input, form handling, or API request processing. Detects uncontrolled property binding enabling privilege escalation.

2Star
1Fork
更新于 1/22/2026
SKILL.md
readonly只读
name
"mass-assignment-anti-pattern"
description

"Security anti-pattern for mass assignment vulnerabilities (CWE-915). Use when generating or reviewing code that creates or updates objects from user input, form handling, or API request processing. Detects uncontrolled property binding enabling privilege escalation."

Mass Assignment Anti-Pattern

Severity: High

Summary

Mass assignment (also known as "autobinding") is a vulnerability that occurs when a web framework automatically binds incoming HTTP request parameters to variables or objects in the application's code. This is a convenient feature, but it becomes a vulnerability when an attacker can inject and set properties they are not supposed to control. The most common example is an attacker submitting a request with a field like "isAdmin": true and having the application blindly save it, escalating their privileges.

The Anti-Pattern

The anti-pattern is directly using a dictionary of user-provided data to create or update a database model without first filtering for allowed properties.

BAD Code Example

# VULNERABLE: The incoming request data is used directly to update the user model.
from flask import request
from db import User, session

@app.route("/api/users/me", methods=["POST"])
def update_profile():
    # Assume user is already authenticated.
    user = get_current_user()

    # Attacker crafts a JSON body:
    # {
    #   "email": "new.email@example.com",
    #   "is_admin": true
    # }
    request_data = request.get_json()

    # Many ORMs allow updating an object from a dictionary.
    # If the User model has an `is_admin` property, it will be updated here.
    for key, value in request_data.items():
        setattr(user, key, value) # Direct, unsafe assignment.

    session.commit()
    return {"message": "Profile updated."}

# The attacker has just made themselves an administrator.

GOOD Code Example

# SECURE: Use a Data Transfer Object (DTO) or an explicit allowlist to control which fields can be updated.
from flask import request
from db import User, session

# Option 1: Use an allowlist of fields.
ALLOWED_UPDATE_FIELDS = {"email", "first_name", "last_name"}

@app.route("/api/users/me", methods=["POST"])
def update_profile_allowlist():
    user = get_current_user()
    request_data = request.get_json()

    for key, value in request_data.items():
        # Only update the attribute if it's in our explicit allowlist.
        if key in ALLOWED_UPDATE_FIELDS:
            setattr(user, key, value)

    session.commit()
    return {"message": "Profile updated."}


# Option 2 (Better): Use a DTO or schema to define and validate the input.
from pydantic import BaseModel, EmailStr

class UserUpdateDTO(BaseModel):
    # This class defines the *only* fields that can be submitted.
    # The `is_admin` field is not here, so it can't be set by the user.
    email: EmailStr
    first_name: str
    last_name: str

@app.route("/api/users/me/dto", methods=["POST"])
def update_profile_dto():
    user = get_current_user()
    try:
        # Pydantic will raise a validation error if extra fields like `is_admin` are present.
        update_data = UserUpdateDTO(**request.get_json())
    except ValidationError as e:
        return {"error": str(e)}, 400

    user.email = update_data.email
    user.first_name = update_data.first_name
    user.last_name = update_data.last_name
    session.commit()
    return {"message": "Profile updated."}

Detection

  • Review update/create logic: Look for any code that takes a user-provided dictionary or object (request.body, params, etc.) and uses it to directly populate a model (e.g., user.update(params), new User(params)).
  • Check for "allowlists" vs. "blocklists": Code that tries to remove bad keys (a blocklist, e.g., del params['is_admin']) is insecure. A new sensitive property could be added to the model later and forgotten in the blocklist. Secure code uses an allowlist to only accept known-good keys.
  • Test API endpoints: Send requests to POST or PUT endpoints with extra, unauthorized fields in the JSON body (e.g., is_admin, role, account_balance) and see if the values are reflected in the API's response or the database.

Prevention

  • [ ] Use an allowlist approach: Never use a blocklist to filter incoming data. Always use an allowlist of properties that are permitted to be set by the user.
  • [ ] Use Data Transfer Objects (DTOs) or dedicated input schemas to strictly define the expected request body. This is the most robust solution.
  • [ ] Set sensitive properties explicitly in your code, outside of any mass assignment operation (e.g., new_user.is_admin = False).
  • [ ] Be aware of framework features: Some frameworks have built-in protections against mass assignment. Understand how to use them correctly.

Related Security Patterns & Anti-Patterns

References

You Might Also Like

Related Skills

coding-agent

coding-agent

179Kdev-codegen

Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.

openclaw avataropenclaw
获取
add-uint-support

add-uint-support

97Kdev-codegen

Add unsigned integer (uint) type support to PyTorch operators by updating AT_DISPATCH macros. Use when adding support for uint16, uint32, uint64 types to operators, kernels, or when user mentions enabling unsigned types, barebones unsigned types, or uint support.

pytorch avatarpytorch
获取
at-dispatch-v2

at-dispatch-v2

97Kdev-codegen

Convert PyTorch AT_DISPATCH macros to AT_DISPATCH_V2 format in ATen C++ code. Use when porting AT_DISPATCH_ALL_TYPES_AND*, AT_DISPATCH_FLOATING_TYPES*, or other dispatch macros to the new v2 API. For ATen kernel files, CUDA kernels, and native operator implementations.

pytorch avatarpytorch
获取
skill-writer

skill-writer

97Kdev-codegen

Guide users through creating Agent Skills for Claude Code. Use when the user wants to create, write, author, or design a new Skill, or needs help with SKILL.md files, frontmatter, or skill structure.

pytorch avatarpytorch
获取

Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or constructors.

oven-sh avataroven-sh
获取

Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.

oven-sh avataroven-sh
获取