Skip to content

fix: check AAAA records in DNS rebinding protection (IPv6 bypass)#742

Open
Gonzih wants to merge 1 commit intogarrytan:mainfrom
Gonzih:fix/dns-rebinding-ipv6
Open

fix: check AAAA records in DNS rebinding protection (IPv6 bypass)#742
Gonzih wants to merge 1 commit intogarrytan:mainfrom
Gonzih:fix/dns-rebinding-ipv6

Conversation

@Gonzih
Copy link
Copy Markdown

@Gonzih Gonzih commented Apr 1, 2026

Problem

resolvesToBlockedIp() in browse/src/url-validation.ts only calls resolve4() — it only checks IPv4 A records. An attacker can bypass the DNS rebinding protection by setting up a hostname that has only an AAAA (IPv6) record pointing to a cloud metadata endpoint (or an IPv6 equivalent). Closes #668.

Example bypass: a domain with only AAAA ::ffff:169.254.169.254 (IPv4-mapped IPv6) would sail right through the existing check.

Fix

  • Added resolve6() alongside resolve4() — both run concurrently via Promise.allSettled
  • Individual failures (e.g. host has no AAAA records) are silently ignored, same as before
  • Added ::ffff:169.254.169.254 and fe80::1 to BLOCKED_METADATA_HOSTS to catch IPv4-mapped and link-local IPv6 metadata patterns
  • Used Promise.allSettled so a failure on one record type doesn't prevent checking the other

Why Promise.allSettled not Promise.all

Many hosts legitimately have no AAAA records. resolve6() throws ENOTFOUND in those cases. Using allSettled collects both results and lets us check all resolved addresses without a try/catch per record type.


sent from mStack

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.

[Security] DNS rebinding protection only checks IPv4 — IPv6 AAAA records bypass

1 participant