Executive brief
djust is a Python web framework for building interactive live views with client-server synchronization. The default `update_model` event handler, exposed on every LiveView, allows remote attackers to set any public view attribute—not just those intended for data binding. An attacker can tamper with authorization flags, business state, or account identifiers by sending crafted WebSocket events, leading to privilege escalation, unauthorized data access, or state corruption.
Technical details
The vulnerability is a mass-assignment / authorization bypass in the `djust.mixins.model_binding.ModelBindingMixin.update_model()` handler, which is included in the base LiveView MRO and thus exposed on every view by default. The handler accepts a client-supplied `field` name and calls `setattr()` to update a view attribute, with weak controls: a 14-entry denylist of framework internals (`FORBIDDEN_MODEL_FIELDS`), rejection of underscore-prefixed names, optional `allowed_model_fields` allowlist (defaults to None = all allowed), and existence check via `hasattr()`. This permits setting any public, existing view attribute—including authorization/ownership/business state fields never exposed via `dj-model=` bindings in the template. Attack vector is the WebSocket (`{type:event, event:"update_model", params:{field, value}}`), requires network access and (for authenticated views) a valid session. Attackers can achieve state tampering, IDOR, privilege escalation, or price/quantity manipulation. Patch: version 1.0.7 restricts the handler to only fields declared with `dj-model=` in the template or requires explicit allowlist configuration.
Affected products
- djust-org djust < 1.0.7
Timeline
- 2026-06-22: disclosed
- 2026-09-16: advisory
- 2026-06-22: patched: Version 1.0.7 released with fix