GHSA-cc7c-9jff-58wj: Pip/djust vulnerability

Published Sep 16, 2026
·
Updated

Impact djust.mixins.modelbinding.ModelBindingMixin provides a default updatemodel event handler and is part of the LiveView base MRO, so every LiveView exposes it. It setattrs a view attribute whose name is client-supplied (field), gated only by: reject -prefixed names; reject a 14-entry denylist of framework internals (FORBIDDENMODELFIELDS); optional allowedmodelfields which defaults to None = allow all; and hasattr existence.

Result: a client can set any public, existing view attribute — not just the fields actually bound with dj-model= in the rendered template. The denylist covers framework plumbing but nothing about developer business/authz state, and the allowlist is opt-in (off by default). A developer who binds one dj-model="search" input and also keeps self.accountid / self.isadmin / self.totalprice as view state does not realize a client can set ALL of them via {type:event, event:"updatemodel", params:{field, value}} over the WebSocket. Type coercion matches the target attribute's type (so "true" -> bool True), aiding the attacker.

Severity High for apps that hold authorization/ownership/business state in public view attributes (the normal djust pattern) -> state tampering / IDOR / authz-flag manipulation; Low otherwise. Default-on across every LiveView. For a public (no-login) view an anonymous client can mass-assign; for an authenticated view a logged-in user can tamper their own session's view state (the IDOR/authz vector when downstream handlers act on it without re-authorizing).

Reproduced: a view with accountid/isadmin/totalprice (none bound with dj-model) had all three set via updatemodel calls.

Patches Restrict the default handler to fields actually exposed via dj-model=: have the template renderer record the bound-field set per render and reject any field outside it (preferred, secure + zero-config); or make allowedmodelfields fail-closed (required). Keep FORBIDDENMODELFIELDS only as defense-in-depth. Add a regression that a non-dj-model public attribute (e.g. isadmin) is rejected while a bound field still updates.

Workarounds Set allowedmodelfields explicitly on every view using dj-model (or subclassing LiveView) to the minimal list of bindable fields; do not keep authorization/ownership state in public view attributes that share the view with dj-model bindings.

References Reproducer + finding writeup retained privately by the maintainer.

Affected Software

1 affected componentFixes available
pip/djust<1.0.7
1.0.7

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/djust to a version that resolves this vulnerability.

    Fixed in 1.0.7
  2. Configuration

    Restrict the default update_model handler to only fields actually exposed via dj-model: set `allowed_model_fields` explicitly on every LiveView using dj-model (or via a subclass) to the minimal list. Do not rely on the default behavior where `allowed_model_fields` defaults to None (allow all).

    LiveView (ModelBindingMixin / update_model handler) allowed_model_fields = set explicitly to a minimal allowlist of bindable dj-model fields
  3. Configuration

    Do not keep authorization/ownership/business state (e.g., `account_id`, `is_admin`, `total_price`) in public LiveView attributes that are present in a view where dj-model bindings exist. Keep such state out of public view attributes that can be mass-assigned via `{type:event, event:"update_model", params:{field,value}}`.

    LiveView templates / view state public view attributes used for authorization/ownership/business state = move out of public view attributes shared with dj-model bindings

Event History

Sep 16, 2026
Advisory Published
via GitHub·01:55 PM
Data Sourced
via GitHub·01:55 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

Which applications are realistically exposed?

Applications using LiveViews are exposed when they keep authorization, ownership, account, or business state in public view attributes. The risk is especially high if those attributes influence later application behavior, such as account selection, administrator status, or pricing.

2

Does this require a non-default configuration?

No. The optional allowed_model_fields control defaults to None, which allows all existing public attributes unless they are underscore-prefixed or appear in the 14-entry framework denylist. Binding only a limited set of fields with dj-model does not restrict the update_model event handler to those fields.

3

What does an attacker need to do to exploit this?

The attacker needs to send an update_model event over the LiveView WebSocket with a chosen field name and value. The target must be an existing public attribute on the view and must not be blocked by the underscore check or framework denylist; values are coerced to the target attribute type.

4

What can be done if patching is not immediately possible?

Define allowed_model_fields for each affected view so that only intended model-bound fields can be updated. Avoid retaining authorization, ownership, or other security-sensitive business state in public LiveView attributes where possible.

5

How can teams identify potentially affected views?

Review LiveViews for public attributes beyond the fields intentionally bound with dj-model, particularly attributes such as account identifiers, privilege flags, and prices. A view is potentially affected when it does not define allowed_model_fields and has public existing attributes that should not be client-modifiable.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203