Safeguard
Security Guides•

Is Django ModelForm fields = '__all__' a mass assignment risk?

Yes, it can be. fields = '__all__' or exclude lets new model fields become editable by users. Use an explicit fields list and test what a form accepts.

Safeguard Security Team
4 min read

It can be. With fields = "all" or exclude, every model field not excluded becomes user editable, including ones added later. Django's docs say to list fields explicitly. An explicit list means a new column such as is_staff or balance stays out of the form until a developer chooses to add it.

What the Django docs warn

The ModelForm documentation says you must explicitly set which fields should be edited in the form using the fields attribute, because failing to do so can easily lead to security problems when a form unexpectedly allows a user to set certain fields, especially when new fields are added to a model. It adds that depending on how the form is rendered, the problem may not even be visible on the web page.

That last sentence is the dangerous part. A browser only submits fields the page shows, but an attacker can send any POST parameter. If the form class accepts a field, it will take the value.

The docs describe the include everything approach as known to be much less secure and to have led to serious exploits on major websites. They still offer two shortcuts, fields = "all" and exclude, for cases where you can guarantee the security concerns do not apply.

A concrete example

class Profile(models.Model):
    display_name = models.CharField(max_length=80)
    bio = models.TextField(blank=True)
    is_verified = models.BooleanField(default=False)

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = "__all__"

The page may only render display name and bio. But a crafted request with is_verified=on is accepted, because the form includes it. The safer version:

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ["display_name", "bio"]

Why exclude is only slightly better

Exclude lists what to remove, so every new field is included by default. The next developer adds a permissions field to the model, forgets the form, and it is editable. An allow list fails closed. An exclude list fails open.

ApproachNew model field becomes editable?
Explicit fields listNo, until added
exclude listYes, until excluded
fields = "all"Yes, always

Where else this pattern appears

The same idea applies outside ModelForm. Serializers in API frameworks, dictionaries unpacked into model constructors, and code that does Model(**request.POST) or loops over request data with setattr all grant the user control over field names. Prefer an explicit mapping from known input names to known attributes.

Review checklist

  1. Search for __all__ and exclude = in form and serializer classes.
  2. For each hit, list the model fields and mark any that a user should never set: roles, ownership, verification flags, prices, internal status.
  3. Replace with an explicit list.
  4. Add a test that posts an extra privileged field and confirms the saved object did not change.
  5. Make code review ask the question whenever a model gains a field.

Try it yourself

Click through it at your own pace, or open it full screen. Notice how code patterns are flagged for review before they reach production.

Quick check

Does hiding a field in the template protect it?

No. The server decides which parameters it accepts. If the form class includes the field, a crafted request can set it.

Is fields = "all" ever acceptable?

Django allows it where you can guarantee the security concerns do not apply, for example a model where every field is safe for any user to edit. Re-check whenever the model changes.

Safeguard's SAST and policy gates can flag risky form patterns in a pull request. A free scan is available.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.