Phoenix (Phoenix Framework), Improper Check for Unusual or Exceptional Conditions (CWE-754), CVE-2026-56812 (High) -DC-Sep2026-2170

Listen to this Post

CVE-2026-56812 is a high-severity vulnerability (CVSS 7.5/10) in the Phoenix JavaScript presence client (assets/js/phoenix/presence.js). The flaw arises from a bare truthiness check (state

</code>) used to test whether a presence already exists locally, rather than an own-property check. Because applications commonly track presences under client-supplied usernames or IDs, the presence key can be attacker-controlled.
When a user joins a presence channel and chooses a key that names an `Object.prototype` member—such as <code>__proto__</code>, <code>constructor</code>, <code>toString</code>, or <code>hasOwnProperty</code>—the lookup `state["__proto__"]` does not resolve to a tracked presence. Instead, it returns JavaScript's built-in `Object.prototype` object, which is truthy. The `if(currentPresence)` guard passes, and the code then evaluates <code>currentPresence.metas.map(m => m.phx_ref)</code>. Since `Object.prototype.metas` is <code>undefined</code>, calling `.map` on it throws an uncaught <code>TypeError</code>.
Phoenix wraps no `try/catch` around channel binding callbacks, so the `TypeError` propagates out of the message handler: `this.state` is never updated and `onSync()` never fires. The malicious key is tracked server-side and re-pushed on every presence update, keeping presence sync permanently broken for every viewer of that channel topic until the attacker leaves. `Presence.syncDiff` uses the same unsafe `state[bash]` existence-check pattern, so presence diffs fail identically.
The impact is per channel topic, not global—presence state is per-topic on the server and per-<code>Presence</code> instance in the browser. This is a read-time confusion of the prototype object, not prototype pollution: the crash occurs on the `state["__proto__"]` read before any `state[bash] = ...` write is reached, so `Object.prototype` is never mutated. The fix builds state and accumulator objects with `Object.create(null)` (or a <code>Map</code>) and gates existence checks with <code>Object.prototype.hasOwnProperty.call(obj, key)</code>. If an application does not pass a client-controlled key to <code>Presence.track</code>, it is not affected.

<h2 style="color: blue;">DailyCVE Form:</h2>

Platform: Phoenix Framework
Version: 1.2.0-rc.0 – 1.5.14, 1.6.0-rc.0 – 1.6.16, 1.7.0-rc.0 – 1.7.23, 1.8.0-rc.0 – 1.8.8
Vulnerability: Improper Check (CWE-754)
Severity: High (CVSS 7.5)
Date: 2026-07-07
Prediction: Patched versions released 2026-07-07 (1.5.15, 1.6.17, 1.7.24, 1.8.9)

<h2 style="color: blue;">What Undercode Say:</h2>

[bash]
Check Phoenix version in mix.exs
grep -E "phoenix.[0-9]+.[0-9]+.[0-9]+" mix.exs
Check package.json for phoenix dependency
cat assets/package.json | grep phoenix
Vulnerable versions:
Phoenix < 1.5.15, < 1.6.17, < 1.7.24, < 1.8.9
// Vulnerable code in assets/js/phoenix/presence.js
// Presence.syncState and Presence.syncDiff use:
let currentPresence = state[bash];
if (currentPresence) {
// Treats Object.prototype as truthy
currentPresence.metas.map(m => m.phx_ref); // TypeError
}
// Fixed code pattern:
let state = Object.create(null); // or use Map
// Existence check:
if (Object.prototype.hasOwnProperty.call(state, key)) {
// Safe to access
}

Exploit: (Educational Purposes!)

// Step 1: Attacker joins a presence channel with a malicious key
channel.join()
.receive("ok", ({presence}) => {
// Step 2: Track presence under Object.prototype member name
Presence.track(channel, {
user: "<strong>proto</strong>", // or "constructor", "toString", "hasOwnProperty"
metas: [/ ... /]
});
});
// Step 3: Server broadcasts presence_state to all topic subscribers
// Step 4: Each viewer's Presence.syncState reads state["<strong>proto</strong>"]
// Step 5: Returns Object.prototype (truthy) -> .metas.map throws TypeError
// Step 6: Presence sync permanently broken for all viewers until attacker leaves
Manual PoC steps:
1. Connect to Phoenix app using Phoenix.Presence
2. Join a presence channel with key: <strong>proto</strong>
3. Observe all viewers' presence sync freezes
4. Leave channel to restore functionality

Protection:

  1. Upgrade Phoenix to patched versions: ≥ 1.5.15, ≥ 1.6.17, ≥ 1.7.24, or ≥ 1.8.9

2. Sanitize presence keys before calling `Phoenix.Presence.track`:

  • Reject keys matching __proto__, constructor, prototype, toString, hasOwnProperty, etc.
  • Namespace keys with a fixed prefix so no key can equal a prototype member name
  1. Derive presence keys from server-controlled, validated values instead of raw user input
  2. Use `Object.create(null)` for state and accumulator objects, or use `Map` instead of plain objects

5. Gate existence checks with `Object.prototype.hasOwnProperty.call(obj, key)`

Impact:

An attacker with ordinary channel access can cause a persistent, stored client-side denial of service against every browser viewing a presence channel topic, freezing presence updates for all of them until the attacker disconnects. Any application driving the Phoenix JavaScript presence client with user-influenced presence keys is affected. The vulnerability is not global—only viewers of the specific topic carrying the malicious key are affected. No data is leaked, and `Object.prototype` is never mutated (not prototype pollution).

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top