Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessOpen WebSocket to LiveView
-
DeliveryEnumerate public view attributes
-
ExploitSend update_model event with target field
-
Executionsetattr overwrites authz/business state
-
ImpactIDOR / privilege or price tampering
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A08:2025 - Software or Data Integrity Failures
ASVS 5.0
V4 - API and Web Service Object attribute protection
|
| Exploitation Conditions | Exploitation requires that the target application (a) uses djust < 1.0.7 with a LiveView that inherits the default ModelBindingMixin (on by default across all LiveViews), (b) does NOT set allowed_model_fields (which defaults to None = allow all), and (c) stores security-relevant state - e.g. self.account_id, self.is_admin, self.total_price - as public, non-underscore view attributes not covered by the 14-entry FORBIDDEN_MODEL_FIELDS denylist. The attacker sends update_model events over the established WebSocket. Limiting factors: impact is high only when authorization/ownership/business logic reads these tamperable attributes without re-authorizing downstream; the target field must already exist (hasattr) and not be underscore-prefixed or on the denylist; for authenticated-only views a valid session is needed (PR:L), whereas public login-free views are exploitable anonymously (effectively PR:N). Setting allowed_model_fields to a minimal list, or upgrading to 1.0.7, closes it. |
| Impact | This is a genuine but conditionally-severe integrity vulnerability, not a hollow high-CVSS entry. The CVSS 4.0 vector (AV:N/AC:L/AT:N/PR:L/UI:N, VC:N/VI:H/VA:N, score 7.1) is well-calibrated to a state-tampering/mass-assignment flaw: pure integrity impact (VI:H), no confidentiality or availability, network-reachable over WebSocket with low complexity and no user interaction. CWE-915 (mass assignment) matches the described behavior exactly. The vendor rates severity as 'High' only for apps that store authorization/ownership/business state in public view attributes (the normal djust pattern) and 'Low' otherwise, so real risk is app-dependent. Note a genuine PR ambiguity: the CVSS uses PR:L (authenticated), but the advisory explicitly states that for a public, no-login LiveView an anonymous client can mass-assign - so for those deployments PR:N is more accurate and effective severity would be higher. No EPSS score, no CISA KEV listing, and no public exploit are provided; the reproducer/writeup is retained privately by the reporter, so this is no public exploit identified at time of analysis. The default-on nature (the mixin is in every LiveView's base MRO) broadens exposure across all djust apps, but the niche footprint of the framework limits absolute scale. |
| Exploit ScenarioDerived | An attacker connects to a djust LiveView over WebSocket and sends {type:event, event:"update_model", params:{field:"is_admin", value:"true"}}, exploiting the default update_model handler that setattrs any public, existing view attribute - even ones never bound with dj-model. With type coercion turning "true" into boolean True, they flip self.is_admin or overwrite self.account_id / self.total_price to tamper with authorization, ownership, or pricing state. No public exploit is published, but the vendor reproduced setting account_id/is_admin/total_price, none of which were dj-model-bound. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 16, 2026
Mass assignment in djust, a Django library providing Phoenix LiveView-style reactive server-side rendering, allows any client with an established WebSocket session to overwrite arbitrary public attributes on a LiveView instance through the framework's default update_model event handler. The handler ships in djust.mixins.model_binding.ModelBindingMixin, which sits in the LiveView base MRO and is therefore exposed by every view, and it setattrs a view attribute whose name is supplied entirely by the client - gated only by a 14-entry framework-internal denylist, an underscore-prefix rejection, and an opt-in allowed_model_fields allowlist that defaults to None (allow all). Affected deployments are djust versions prior to 1.0.7 that leave the allowlist unset and keep authorization, ownership, or business state such as self.account_id, self.is_admin, or self.total_price as public view attributes; the advisory's own reproducer set all three without any dj-model binding. Exploitation yields state tampering that can escalate to authorization-flag manipulation or IDOR when downstream handlers act on the tampered attributes without re-authorizing, giving a High integrity impact with no confidentiality or availability impact (assessed CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N); no public exploit code was identified at time of analysis and there is no CISA KEV entry, though the vendor retained a private reproducer.
RemediationAI
Upgrade to djust 1.0.7 (Vendor-released patch: 1.0.7), which restricts the default handler so only fields actually exposed via dj-model= can be written, per the security advisory at https://github.com/djust-org/djust/security/advisories/GHSA-cc7c-9jff-58wj and the release at https://github.com/djust-org/djust/releases/tag/v1.0.7. If upgrading immediately is not possible, the vendor's workaround is to set allowed_model_fields explicitly on every view that uses dj-model= or subclasses LiveView, enumerating the minimal list of genuinely bindable fields; the trade-off is that this is easy to forget on new views and will cause legitimate dj-model updates to be silently rejected if a bound field is omitted from the list. As a second compensating control, stop storing authorization, ownership, or pricing state (account_id, is_admin, total_price, etc.) as public, non-underscore view attributes on any view that also carries dj-model bindings - either move that state into underscore-prefixed private attributes or application-level session/DB lookups, or re-authorize the resource server-side inside every downstream handler so tampered view state cannot translate into unauthorized actions; the trade-off is refactoring effort and the risk of leaving residual public state that the 14-entry FORBIDDEN_MODEL_FIELDS denylist does not cover. Note that FORBIDDEN_MODEL_FIELDS should be treated only as defense-in-depth, since it covers framework plumbing and not developer-defined business or authorization attributes.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The root cause is CWE-915, Improperly Controlled Modification of Dynamically-Determined Object Attributes - classic mass assignment implemented through Python's setattr. In djust's architecture, LiveView state lives as instance attributes that are re-rendered server-side and synced to the browser over a WebSocket; dj-model= bindings in a template are intended to map specific inputs to specific attributes. ModelBindingMixin.update_model instead accepts a {type:event, event:"update_model", params:{field, value}} message where field is an arbitrary client-chosen string, and writes it directly onto the view object if the name is not underscore-prefixed, is not one of the 14 FORBIDDEN_MODEL_FIELDS framework internals, passes the optional allowed_model_fields check (which defaults to None, meaning everything is permitted), and passes a hasattr existence test. The write is also type-coerced to match the existing attribute's type, so a JSON string "true" becomes the Python boolean True for a boolean target, which makes tampering with flags such as is_admin trivial and avoids obvious type errors. The design flaw is that the guardrails describe framework plumbing rather than application semantics: the denylist says nothing about developer business or authorization state, and the allowlist is opt-in rather than fail-closed, so the secure configuration requires deliberate developer action. The upstream advisory recommends that the template renderer record the set of fields actually exposed via dj-model= for each render and reject any field outside that set, which would make the default secure with zero configuration, or alternatively require allowed_model_fields to be set explicitly.
Know when Djust gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
Network WebSocket, low complexity, no UI; PR:L for the common authenticated-view case (public views would be PR:N); pure integrity state-tampering so C:N/A:N.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
djust provides Phoenix LiveView-style reactive server-side rendering for Django with Rust-powered performance. Prior to version 1.0.7, djust.mixins.model_binding.ModelBindingMixin provides a default update_model 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 (FORBIDDEN_MODEL_FIELDS); optional allowed_model_fields which defaults to None = allow all; and hasattr existence. As a 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.account_id / self.is_admin / self.total_price as view state does not realize a client can set ALL of them via {type:event, event:"update_model", params:{field, value}} over the WebSocket. Type coercion matches the target attribute's type (so "true" -> bool True), aiding the attacker. This issue is fixed in djust 1.0.7. As a workaround, set allowed_model_fields 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.
Technical POC Analysis
CWE-915 (Improperly Controlled Modification of Dynamically-Determined Object Attributes).
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Latest POC
1 PoC candidate from github (unverified)
Sign in to open the public PoC links collected for this CVE.
Executive ViewAI
djust, a Django library that adds Phoenix LiveView-style reactive rendering to Python web applications, allows any client holding an established WebSocket session to silently rewrite internal view state on a running LiveView - including the very fields applications use to track account ownership, administrator status, and order pricing. Because the vulnerable handler is inherited by every view in the framework's default configuration, exposure is not limited to a handful of unusual components; it applies broadly to any application running an affected djust release with default settings. Leadership should treat this as a live authorization-bypass and financial-integrity risk to customer-facing application logic rather than a localized coding defect.
No vendor-released patch identified at time of analysis. Interim mitigations: set an explicit allowed_model_fields allowlist on every LiveView (never leave it at the default of None); override or remove the update_model handler inherited from djust.mixins.model_binding.ModelBindingMixin so client-supplied attribute names cannot reach setattr; relocate authorization, ownership, and business state such as account_id, is_admin, and total_price out of public view attributes; require authentication and rate-limit or alert on LiveView WebSocket attribute-write events; monitor application and WebSocket logs for anomalous attribute writes pending upgrade.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Authentication bypass in djust's WebSocket LiveView consumer allows unauthenticated remote clients to invoke protected e
Cross-site request forgery in djust's Server-Sent-Events transport affects all versions prior to 1.0.7 and allows a cros
Unauthenticated remote attackers can read live Django view and session state and invoke server-side handlers through dju
EUVD-2026-80768
GHSA-cc7c-9jff-58wj
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB