{"id":"EEF-CVE-2026-56812","summary":"Phoenix JavaScript presence client crashes on presence keys colliding with Object.prototype members in Presence.syncState/syncDiff","details":"## Summary\n\nImproper 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.\n\nThis vulnerability is associated with program files `assets/js/phoenix/presence.js` and program routines `Presence.syncState` and `Presence.syncDiff`.\n\nThe 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`.\n\nThe 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).\n\nThis 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.\n\n## Workarounds\n\nReject 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.\n\n## Configurations\n\nThe application must use `Phoenix.Presence` (or otherwise drive the Phoenix JavaScript presence client) and track presences under keys that are influenced by untrusted client input, for example a username or id chosen by the connecting user. Applications that derive presence keys exclusively from server-controlled, validated values are not affected.","aliases":["CVE-2026-56812","GHSA-63mc-hw7g-86rr"],"modified":"2026-09-24T21:30:04.371807137Z","published":"2026-07-07T15:22:46.933Z","database_specific":{"capec_ids":["CAPEC-153"],"cpe_ids":["cpe:2.3:a:phoenixframework:phoenix:*:*:*:*:*:*:*:*"],"cwe_ids":["CWE-754"]},"references":[{"type":"ADVISORY","url":"https://github.com/phoenixframework/phoenix/security/advisories/GHSA-63mc-hw7g-86rr"},{"type":"WEB","url":"https://cna.erlef.org/cves/CVE-2026-56812.html"},{"type":"WEB","url":"https://github.com/phoenixframework/phoenix/commit/2270aaf21bd02c6a6a1022820564efb605a97655"},{"type":"FIX","url":"https://github.com/phoenixframework/phoenix/commit/7f7b971c1ea0994e3fbd1c11ddb05e780bd38ad8"},{"type":"FIX","url":"https://github.com/phoenixframework/phoenix/commit/89a1c4be161e436241e12b2378a719904b9bd96f"},{"type":"FIX","url":"https://github.com/phoenixframework/phoenix/commit/b90b22521465ece00eb5a19d5aa2b9465b209c85"},{"type":"FIX","url":"https://github.com/phoenixframework/phoenix/commit/beffc4da1e787e572121f68902c63daf4fe7d9c2"},{"type":"PACKAGE","url":"https://hex.pm/packages/phoenix"},{"type":"PACKAGE","url":"https://www.npmjs.com/package/phoenix"}],"affected":[{"package":{"name":"phoenix","ecosystem":"Hex","purl":"pkg:hex/phoenix"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.2.0-rc.0"},{"fixed":"1.5.15"}]},{"type":"SEMVER","events":[{"introduced":"1.6.0-rc.0"},{"fixed":"1.6.17"}]},{"type":"SEMVER","events":[{"introduced":"1.7.0-rc.0"},{"fixed":"1.7.24"}]},{"type":"SEMVER","events":[{"introduced":"1.8.0-rc.0"},{"fixed":"1.8.9"}]}],"versions":["1.2.0","1.2.0-rc.0","1.2.0-rc.1","1.2.1","1.2.2","1.2.3","1.2.4","1.2.5","1.3.0","1.3.0-rc.0","1.3.0-rc.1","1.3.0-rc.2","1.3.0-rc.3","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.4.0","1.4.0-rc.0","1.4.0-rc.1","1.4.0-rc.2","1.4.0-rc.3","1.4.1","1.4.10","1.4.11","1.4.12","1.4.13","1.4.14","1.4.15","1.4.16","1.4.17","1.4.18","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.4.8","1.4.9","1.5.0","1.5.0-rc.0","1.5.1","1.5.10","1.5.11","1.5.12","1.5.13","1.5.14","1.5.2","1.5.3","1.5.4","1.5.5","1.5.6","1.5.7","1.5.8","1.5.9","1.6.0","1.6.0-rc.0","1.6.0-rc.1","1.6.1","1.6.10","1.6.11","1.6.12","1.6.13","1.6.14","1.6.15","1.6.16","1.6.2","1.6.3","1.6.4","1.6.5","1.6.6","1.6.7","1.6.8","1.6.9","1.7.0","1.7.0-rc.0","1.7.0-rc.1","1.7.0-rc.2","1.7.0-rc.3","1.7.1","1.7.10","1.7.11","1.7.12","1.7.13","1.7.14","1.7.15","1.7.16","1.7.17","1.7.18","1.7.19","1.7.2","1.7.20","1.7.21","1.7.22","1.7.23","1.7.3","1.7.4","1.7.5","1.7.6","1.7.7","1.7.8","1.7.9","1.8.0","1.8.0-rc.0","1.8.0-rc.1","1.8.0-rc.2","1.8.0-rc.3","1.8.0-rc.4","1.8.1","1.8.2","1.8.3","1.8.4","1.8.5","1.8.6","1.8.7","1.8.8"],"database_specific":{"source":"https://cna.erlef.org/osv/EEF-CVE-2026-56812.json"}},{"package":{"name":"phoenix","ecosystem":"npm","purl":"pkg:npm/phoenix"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.2.0-rc.0"},{"fixed":"1.5.15"}]},{"type":"SEMVER","events":[{"introduced":"1.6.0-rc.0"},{"fixed":"1.6.17"}]},{"type":"SEMVER","events":[{"introduced":"1.7.0-rc.0"},{"fixed":"1.7.24"}]},{"type":"SEMVER","events":[{"introduced":"1.8.0-rc.0"},{"fixed":"1.8.9"}]}],"database_specific":{"source":"https://cna.erlef.org/osv/EEF-CVE-2026-56812.json"}},{"ranges":[{"type":"GIT","repo":"https://github.com/phoenixframework/phoenix","events":[{"introduced":"2270aaf21bd02c6a6a1022820564efb605a97655"},{"fixed":"7f7b971c1ea0994e3fbd1c11ddb05e780bd38ad8"},{"fixed":"89a1c4be161e436241e12b2378a719904b9bd96f"},{"fixed":"b90b22521465ece00eb5a19d5aa2b9465b209c85"},{"fixed":"beffc4da1e787e572121f68902c63daf4fe7d9c2"}]}],"versions":["v1.5.13","v1.6.16","v1.7.23","v1.8.8","v1.8.7","v1.8.6","v1.7.22","v1.8.5","v1.8.4","v1.8.3","v1.8.2","v1.8.1","v1.8.0","v1.8.0-rc.4","v1.8.0-rc.3","v1.8.0-rc.2","v1.8.0-rc.1","v1.8.0-rc.0","v1.7.20","v1.7.19","v1.7.18","v1.7.16","v1.7.15","v1.7.14","v1.7.13","v1.7.12","v1.7.11","v1.7.10","v1.7.9","v1.7.8","v1.7.7","v1.7.6","v1.7.5","v1.7.4","v1.7.3","v1.7.2","v1.7.1","v1.7.0","v1.7.0-rc.3","v1.7.0-rc.2","v1.7.0-rc.1","v1.7.0-rc.0","v1.6.15","v1.6.14","v1.6.13","v1.6.12","v1.6.11","v1.6.10","v1.6.7","v1.6.6","v1.6.5","v1.6.4","v1.6.3","v1.6.2","v1.6.1","v1.6.0","v1.6.0-rc.1","v1.6.0-rc.0","v1.5.12","v1.5.11","v1.5.10","v1.5.9","v1.5.8","v1.5.7","v1.5.6","v1.5.5","v1.5.4","v1.5.3","v1.5.2","v1.5.1","v1.5.0","v1.5.0-rc.0","v1.4.0","v1.4.0-rc.3","v1.4.0-rc.2","v1.4.0-rc.1","v1.4.0-rc.0","v1.3.0","v1.3.0-rc.3","v1.3.0-rc.2","v1.3.0-rc.1","v1.3.0-rc.0","v1.2.0","v1.2.0-rc.1","v1.2.0-rc.0"],"database_specific":{"source":"https://cna.erlef.org/osv/EEF-CVE-2026-56812.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V4","score":"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"}],"credits":[{"name":"Peter Ullrich","type":"FINDER"},{"name":"Jonatan Männchen / EEF","type":"ANALYST"},{"name":"José Valim","type":"ANALYST"},{"name":"Steffen Deusch","type":"REMEDIATION_DEVELOPER"}]}