Severity by source
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
S:C applied because attacker's channel join causes availability loss in other users' independent client sessions, crossing a security boundary; PR:N reflects ordinary channel access; A:L limited to presence sync disruption.
Primary rating from Vendor (EEF).
CVSS VectorVendor: EEF
Lifecycle Timeline
1DescriptionCVE.org
Improper Check for Unusual or Exceptional Conditions vulnerability in phoenixframework phoenix (Presence JavaScript client) allows an attacker with ordinary channel access to cause a persistent client-side denial of service against every viewer of a presence channel topic.
This vulnerability is associated with program files assets/js/phoenix/presence.js and program routines Presence.syncState and Presence.syncDiff.
The Phoenix JavaScript presence client checks whether a presence already exists with a bare truthiness test (state[key]) instead of an own-property check. Presence keys are attacker-controlled, because applications track presences under a username or id supplied by the client. A user who joins a channel choosing a key that is an Object.prototype member name (__proto__, constructor, toString, hasOwnProperty, and similar) makes that lookup return JavaScript's built-in Object.prototype instead of undefined. Because the prototype is truthy, the code treats it as an existing presence and reads .metas.map(...) off it, which throws an uncaught TypeError.
The exception propagates out of the presence message handler, so the local state is never updated and onSync() never fires. Because the malicious key is tracked on the server, it is re-pushed on every presence update and keeps re-throwing, so presence sync stays broken for every viewer of that channel topic until the attacker leaves. Both syncState and syncDiff use the same unsafe existence-check pattern. The impact is limited to the affected topic and is a read-time confusion of the prototype object, not a mutation of Object.prototype (it is not prototype pollution).
This issue affects phoenix: from 1.2.0 before 1.5.15, from 1.6.0 before 1.6.17, from 1.7.0 before 1.7.24, and from 1.8.0 before 1.8.9.
AnalysisAI
Phoenix Framework's Presence JavaScript client allows any user with ordinary channel access to permanently break presence synchronization for all other viewers of an affected channel topic. By joining a channel using a key name that collides with an Object.prototype property (such as '__proto__', 'constructor', or 'toString'), an attacker causes an uncaught TypeError inside Presence.syncState and Presence.syncDiff that halts all further presence updates for every connected viewer until the attacker disconnects. This is not in CISA KEV, no public exploit has been identified, and the CVSS 4.0 score of 6.3 reflects the limited but persistent client-side availability impact with no server-side exposure.
Technical ContextAI
The vulnerability resides in assets/js/phoenix/presence.js within the Presence.syncState and Presence.syncDiff routines (CPE: cpe:2.3:a:phoenixframework:phoenix:*:*:*:*:*:*:*:*). Both functions maintain a local presence map and check whether a given key already exists using a bare property access (state[key]) rather than an own-property guard such as Object.prototype.hasOwnProperty.call(state, key) or Object.hasOwn(state, key). In JavaScript, bare bracket notation traverses the prototype chain, so any key that matches a built-in Object.prototype member resolves to the prototype object itself instead of undefined. Because the prototype is truthy, the existence check passes, and the code then tries to call .metas.map() on the prototype - which has no such property - throwing a TypeError. CWE-754 (Improper Check for Unusual or Exceptional Conditions) precisely captures this root cause: the code fails to account for the exceptional case where JavaScript's implicit prototype inheritance makes a bare key lookup return an unexpected truthy value. Critically, this is a read-time confusion, not prototype pollution; Object.prototype is never mutated.
RemediationAI
Upgrade to the patched release for your version branch: Phoenix 1.5.15, 1.6.17, 1.7.24, or 1.8.9. Four patch commits are publicly available on GitHub (7f7b971c1ea0994e3fbd1c11ddb05e780bd38ad8, 89a1c4be161e436241e12b2378a719904b9bd96f, b90b22521465ece00eb5a19d5aa2b9465b209c85, beffc4da1e787e572121f68902c63daf4fe7d9c2); the vendor security advisory at https://github.com/phoenixframework/phoenix/security/advisories/GHSA-63mc-hw7g-86rr provides full context. If immediate upgrade is not feasible, a compensating control is to validate and reject presence keys on the server side before they are broadcast: specifically, reject any join or presence tracking request whose key matches a reserved JavaScript Object.prototype property name (__proto__, constructor, toString, valueOf, hasOwnProperty, isPrototypeOf, propertyIsEnumerable, toLocaleString). The trade-off is that this deny-list must be maintained as JavaScript evolves and requires application-level custom channel join callbacks. Alternatively, applications that assign server-generated numeric or UUID presence keys rather than accepting free-form client-supplied strings are not exploitable regardless of library version.
The Phoenix Framework versions 1.0.0 through 1.0.4, 1.1.0 through 1.1.6, 1.2.0, 1.2.2 and 1.3.0-rc.0 are vulnerable to u
In Phoenix SCT WinFlash 1.1.12.0 through 1.5.74.0, the included drivers could be used by a malicious Windows application
Denial of service in the Phoenix Framework (Elixir) affects any endpoint mounting a Phoenix.Socket with a reachable WebS
Unauthenticated remote denial-of-service in Phoenix Framework 1.7.0-1.7.21 and 1.8.0-1.8.5 allows attackers to crash Eli
socket/transport.ex in Phoenix before 1.6.14 mishandles check_origin wildcarding. Rated high severity (CVSS 7.5), this v
Same technique Denial Of Service
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-42050
GHSA-63mc-hw7g-86rr