Skip to content

fix(cors): prevent SSRF via DNS rebinding#4090

Merged
khassel merged 1 commit intoMagicMirrorOrg:developfrom
KristjanESPERANTO:cors
Apr 4, 2026
Merged

fix(cors): prevent SSRF via DNS rebinding#4090
khassel merged 1 commit intoMagicMirrorOrg:developfrom
KristjanESPERANTO:cors

Conversation

@KristjanESPERANTO
Copy link
Copy Markdown
Collaborator

PR #4084 blocked SSRF by checking the IP before fetch() — but fetch() resolves DNS again on its own. With DNS rebinding (TTL=0, alternating IPs) an attacker can slip a private IP through between check and connection.

Fix: resolve DNS once, validate, pin the validated IP for the connection.

No second DNS query → no rebinding window. isPrivateTarget() is gone, code is shorter than before.

Not a likely attack for a typical MagicMirror setup, but it doesn't add complexity so there's no reason not to close the gap.

Replace isPrivateTarget() + fetch() two-step (vulnerable to TOCTOU /
DNS rebinding) with resolve-then-pin: DNS is resolved once, the IP is
validated, and the validated IP is pinned via an undici Agent dispatcher
so fetch() cannot re-resolve to a different address.

- Block localhost, non-http protocols and invalid URLs before DNS
- Resolve hostname via dns.promises.lookup, reject non-unicast IPs
- Pin validated IP in undici Agent lookup callback
- Remove isPrivateTarget() (no longer needed)
- Update tests to mock dns.promises.lookup and global.fetch
@khassel khassel merged commit 96c18ec into MagicMirrorOrg:develop Apr 4, 2026
12 checks passed
@KristjanESPERANTO KristjanESPERANTO deleted the cors branch April 4, 2026 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants