-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
fix(DnsPinMiddlware): only pass punycode/ASCII hostname to dns_get_record
#56197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…cord `dns_get_record()` only supports ASCII/Punycode input. `idn_to_utf8()` converts Punycode/ASCII hostnames to their Unicode form. If we pass it raw Unicode (e.g., "bücher.com"), it returns it unchanged. If you give it Punycode (e.g., "xn--bcher-kva.com"), it returns the Unicode (e.g., "bücher.com"). Neither of which will work with dns_get_record(). Passing either raw Unicode or the output of idn_to_utf8() on a punycode string to dns_get_record() will result in DNS resolution failure for IDNs. Only ASCII/punycode should be passed to the resolver. Signed-off-by: Josh <josh.t.richards@gmail.com>
Add tests for DNS pinning middleware handling of Punycode and Unicode hostnames. Signed-off-by: Josh <josh.t.richards@gmail.com>
|
/backport to stable32 |
|
/backport to stable31 |
Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you 👍
I'd agree we want to use idn_to_ascii and not idn_to_utf8 🙈
| } | ||
|
|
||
| $targetIps = $this->dnsResolve(idn_to_utf8($hostName), 0); | ||
| $targetIps = $this->dnsResolve(idn_to_ascii($hostName, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, null), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| $targetIps = $this->dnsResolve(idn_to_ascii($hostName, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46, null), 0); | |
| $targetIps = $this->dnsResolve(idn_to_ascii($hostName, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46), 0); |
| ->with( | ||
| $this->callback(function ($hostname) use ($punycodeHost) { | ||
| // Should never be raw Unicode here! | ||
| $this->assertEquals($punycodeHost, $hostname, "dnsGetRecord should be called with Punycode ASCII host"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| $this->assertEquals($punycodeHost, $hostname, "dnsGetRecord should be called with Punycode ASCII host"); | |
| $this->assertEquals($punycodeHost, $hostname, 'dnsGetRecord should be called with Punycode ASCII host'); |
For a happy linter ;)
Summary
tldr: The current use of
idn_to_utf8()in this context breaks DNS resolution for both Unicode IDNs and explicit punycode hostnames. It also doesn't seem to match the intention.Likely also fixes #53185
Details
dns_get_record()only supports ASCII/Punycode input.idn_to_utf8()converts Punycode/ASCII hostnames to their Unicode form.If we pass it raw Unicode (e.g., "bücher.com"), it returns it unchanged. If you give it Punycode (e.g., "xn--bcher-kva.com"), it returns the Unicode (e.g., "bücher.com").
Neither of which will work with
dns_get_record().Passing either raw Unicode or the output of
idn_to_utf8()on a punycode string todns_get_record()will result in DNS resolution failure for IDNs. Only ASCII/punycode should be passed to the resolver.Not caught by unit tests previously due to ASCII-only hostnames, mocked DNS, etc.
TODO
server/lib/private/Security/RemoteHostValidator.php
Line 38 in 9581230
Checklist
3. to review, feature component)stable32)