Description
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 can be 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-rc.0 before 1.5.15, from 1.6.0-rc.0 before 1.6.17, from 1.7.0-rc.0 before 1.7.24, and from 1.8.0-rc.0 before 1.8.9; phoenix: from 1.2.0-rc.0 before 1.5.15, from 1.6.0-rc.0 before 1.6.17, from 1.7.0-rc.0 before 1.7.24, and from 1.8.0-rc.0 before 1.8.9.
Published: 2026-07-07
Score: 6.3 Medium
EPSS: < 1% Very Low
KEV: No
Impact: Client‑side Denial of Service
Action: Patch Immediately
AI Analysis

Impact

The Phoenix JavaScript presence client performs a simple truthiness check for presence existence rather than verifying the presence of an own property. Because presence keys can be supplied by the client, an attacker may choose a key that matches a member of JavaScript’s Object.prototype, such as __proto__ or constructor. When the client looks up that key, the lookup returns the built‑in Object.prototype instead of undefined. The prototype object is truthy, so the code treats it as an existing presence and attempts to read .metas.map(...) from it, triggering an uncaught TypeError. The error propagates out of the presence message handler, leaving local state unupdated and preventing the onSync() callback from firing. Since the malicious key is echoed by the server on each presence update, every viewer of that channel experiences a persistent client‑side denial of service until the offending user disconnects. The defect does not alter Object.prototype, nor does it allow code execution; it merely causes a continuous crash of the presence sync logic for the affected topic.

Affected Systems

The issue is present in the Phoenix framework’s JavaScript presence client shipped with Phoenix. Versions affected are all releases from 1.2.0‑rc.0 up to, but not including, 1.5.15; 1.6.0‑rc.0 up to, but not including, 1.6.17; 1.7.0‑rc.0 up to, but not including, 1.7.24; and 1.8.0‑rc.0 up to, but not including, 1.8.9. Applications that allow users to provide arbitrary presence identifiers such as usernames or session IDs without validation are vulnerable.

Risk and Exploitability

An attacker with ordinary channel access can supply a malicious presence key. The resulting TypeError propagates out of the sync handler but is not caught by higher‑level code, leaving the client in a broken state until the offending user disconnects. The CVSS score of 6.3 indicates moderate severity. The EPSS score of <1% implies a low likelihood of exploitation in the wild, and the vulnerability is not listed in CISA’s KEV catalog. Nonetheless, because the exploit requires only normal user privileges and can continuously disrupt the user interface of affected channels, the risk remains material for exposed or public channels.

Generated by OpenCVE AI on September 26, 2026 at 06:12 UTC.

Remediation

Vendor Workaround

Reject or sanitize presence keys that collide with JavaScript Object.prototype member names (for example __proto__, constructor, prototype, toString, hasOwnProperty) before calling Phoenix.Presence.track, or namespace every presence key with a fixed prefix so that no key can equal a prototype member name. Alternatively, derive presence keys from server-controlled, validated values instead of raw user input.


OpenCVE Recommended Actions

  • Update Phoenix to a version newer than the fixed releases (i.e., any release beyond 1.8.9).
  • If an upgrade is not immediately possible, reject or sanitize presence keys that collide with Object.prototype members (such as __proto__, constructor, prototype, toString, hasOwnProperty) before calling Phoenix.Presence.track, or enforce a fixed namespace prefix so that no key can equal a prototype member name.
  • If the application continues to rely on user‑supplied presence keys, modify the key generation logic so that keys are derived from server‑controlled, validated values rather than raw client input.

Generated by OpenCVE AI on September 26, 2026 at 06:12 UTC.

Tracking

Sign in to view the affected projects.

Advisories
Source ID Title
Github GHSA Github GHSA GHSA-63mc-hw7g-86rr Phoenix: Presence keys colliding with `Object.prototype` members break existence checks
History

Thu, 24 Sep 2026 21:45:00 +0000

Type Values Removed Values Added
Description 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 can be 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-rc.0 before 1.5.15, from 1.6.0-rc.0 before 1.6.17, from 1.7.0-rc.0 before 1.7.24, and from 1.8.0-rc.0 before 1.8.9. 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 can be 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-rc.0 before 1.5.15, from 1.6.0-rc.0 before 1.6.17, from 1.7.0-rc.0 before 1.7.24, and from 1.8.0-rc.0 before 1.8.9; phoenix: from 1.2.0-rc.0 before 1.5.15, from 1.6.0-rc.0 before 1.6.17, from 1.7.0-rc.0 before 1.7.24, and from 1.8.0-rc.0 before 1.8.9.
References

Tue, 07 Jul 2026 17:30:00 +0000

Type Values Removed Values Added
Metrics ssvc

{'options': {'Automatable': 'no', 'Exploitation': 'poc', 'Technical Impact': 'partial'}, 'version': '2.0.3'}


Tue, 07 Jul 2026 16:45:00 +0000

Type Values Removed Values Added
Description 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. 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 can be 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-rc.0 before 1.5.15, from 1.6.0-rc.0 before 1.6.17, from 1.7.0-rc.0 before 1.7.24, and from 1.8.0-rc.0 before 1.8.9.

Tue, 07 Jul 2026 16:00:00 +0000

Type Values Removed Values Added
Description 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.
Title Phoenix JavaScript presence client crashes on presence keys colliding with Object.prototype members in Presence.syncState/syncDiff
First Time appeared Phoenixframework
Phoenixframework phoenix
Weaknesses CWE-754
CPEs cpe:2.3:a:phoenixframework:phoenix:*:*:*:*:*:*:*:*
Vendors & Products Phoenixframework
Phoenixframework phoenix
References
Metrics cvssV4_0

{'score': 6.3, 'vector': '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'}


Subscriptions

Phoenixframework Phoenix
cve-icon MITRE

Status: PUBLISHED

Assigner: EEF

Published:

Updated: 2026-09-24T21:29:18.181Z

Reserved: 2026-06-23T12:29:02.507Z

Link: CVE-2026-56812

cve-icon Vulnrichment

Updated: 2026-07-07T16:10:49.072Z

cve-icon NVD

Status : Modified

Published: 2026-07-07T16:16:40.920

Modified: 2026-09-24T22:17:00.683

Link: CVE-2026-56812

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-09-26T06:15:06Z

Weaknesses
  • CWE-754

    Improper Check for Unusual or Exceptional Conditions