Skip to content

Commit 5bc0ba6

Browse files
committed
fix(DnsPinning): Ensure to always lookup based on FQDN
Signed-off-by: David Dreschner <david.dreschner@nextcloud.com>
1 parent 753e6ee commit 5bc0ba6

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

lib/private/Http/Client/DnsPinMiddleware.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ public function __construct(
2525
) {
2626
}
2727

28+
/**
29+
* DNS lookups must end with a dot to be marked as
30+
* FQDN. Otherwise, a record without answer may trigger
31+
* a lookup on the local domain name. See GitHub
32+
* issue #56489 for details.
33+
*/
34+
private function enforceFqdn(string $hostname): string {
35+
$trimmedHostname = rtrim($hostname, '.');
36+
return "$trimmedHostname.";
37+
}
38+
2839
/**
2940
* Fetch soa record for a target
3041
*/
@@ -35,7 +46,7 @@ private function soaRecord(string $target): ?array {
3546
$second = array_pop($labels);
3647

3748
$hostname = $second . '.' . $top;
38-
$responses = $this->dnsGetRecord($hostname, DNS_SOA);
49+
$responses = $this->dnsGetRecord($this->enforceFqdn($hostname), DNS_SOA);
3950

4051
if ($responses === false || count($responses) === 0) {
4152
return null;
@@ -68,7 +79,7 @@ private function dnsResolve(string $target, int $recursionCount) : array {
6879
continue;
6980
}
7081

71-
$dnsResponses = $this->dnsGetRecord($target, $dnsType);
82+
$dnsResponses = $this->dnsGetRecord($this->enforceFqdn($target), $dnsType);
7283
if ($dnsResponses !== false && count($dnsResponses) > 0) {
7384
foreach ($dnsResponses as $dnsResponse) {
7485
if (isset($dnsResponse['ip'])) {

tests/lib/Http/Client/DnsPinMiddlewareTest.php

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static function (RequestInterface $request, array $options) {
6161
->method('dnsGetRecord')
6262
->willReturnCallback(function (string $hostname, int $type) {
6363
// example.com SOA
64-
if ($hostname === 'example.com') {
64+
if ($hostname === 'example.com.') {
6565
return match ($type) {
6666
DNS_SOA => [
6767
[
@@ -76,7 +76,7 @@ static function (RequestInterface $request, array $options) {
7676
}
7777

7878
// example.com A, AAAA, CNAME
79-
if ($hostname === 'www.example.com') {
79+
if ($hostname === 'www.example.com.') {
8080
return match ($type) {
8181
DNS_A => [],
8282
DNS_AAAA => [],
@@ -93,7 +93,7 @@ static function (RequestInterface $request, array $options) {
9393
}
9494

9595
// example.net SOA
96-
if ($hostname === 'example.net') {
96+
if ($hostname === 'example.net.') {
9797
return match ($type) {
9898
DNS_SOA => [
9999
[
@@ -108,7 +108,7 @@ static function (RequestInterface $request, array $options) {
108108
}
109109

110110
// example.net A, AAAA, CNAME
111-
if ($hostname === 'www.example.net') {
111+
if ($hostname === 'www.example.net.') {
112112
return match ($type) {
113113
DNS_A => [
114114
[
@@ -154,7 +154,7 @@ static function (RequestInterface $request, array $options) {
154154
->method('dnsGetRecord')
155155
->willReturnCallback(function (string $hostname, int $type) {
156156
// example.com SOA
157-
if ($hostname === 'example.com') {
157+
if ($hostname === 'example.com.') {
158158
return match ($type) {
159159
DNS_SOA => [
160160
[
@@ -169,7 +169,7 @@ static function (RequestInterface $request, array $options) {
169169
}
170170

171171
// example.com A, AAAA, CNAME
172-
if ($hostname === 'www.example.com') {
172+
if ($hostname === 'www.example.com.') {
173173
return match ($type) {
174174
DNS_A => [],
175175
DNS_AAAA => [],
@@ -186,7 +186,7 @@ static function (RequestInterface $request, array $options) {
186186
}
187187

188188
// example.net SOA
189-
if ($hostname === 'example.net') {
189+
if ($hostname === 'example.net.') {
190190
return match ($type) {
191191
DNS_SOA => [
192192
[
@@ -201,7 +201,7 @@ static function (RequestInterface $request, array $options) {
201201
}
202202

203203
// example.net A, AAAA, CNAME
204-
if ($hostname === 'www.example.net') {
204+
if ($hostname === 'www.example.net.') {
205205
return match ($type) {
206206
DNS_A => [
207207
[
@@ -378,7 +378,7 @@ static function (RequestInterface $request, array $options): void {
378378
->method('dnsGetRecord')
379379
->willReturnCallback(function (string $hostname, int $type) {
380380
// example.com SOA
381-
if ($hostname === 'example.com') {
381+
if ($hostname === 'example.com.') {
382382
return match ($type) {
383383
DNS_SOA => [
384384
[
@@ -393,7 +393,7 @@ static function (RequestInterface $request, array $options): void {
393393
}
394394

395395
// example.com A, AAAA, CNAME
396-
if ($hostname === 'www.example.com') {
396+
if ($hostname === 'www.example.com.') {
397397
return match ($type) {
398398
DNS_A => [],
399399
DNS_AAAA => [],
@@ -410,7 +410,7 @@ static function (RequestInterface $request, array $options): void {
410410
}
411411

412412
// example.net SOA
413-
if ($hostname === 'example.net') {
413+
if ($hostname === 'example.net.') {
414414
return match ($type) {
415415
DNS_SOA => [
416416
[
@@ -425,7 +425,7 @@ static function (RequestInterface $request, array $options): void {
425425
}
426426

427427
// example.net A, AAAA, CNAME
428-
if ($hostname === 'www.example.net') {
428+
if ($hostname === 'www.example.net.') {
429429
return match ($type) {
430430
DNS_A => [
431431
[
@@ -496,7 +496,7 @@ static function (RequestInterface $request, array $options): void {
496496
$dnsQueries[] = $hostname . $type;
497497

498498
// example.com SOA
499-
if ($hostname === 'example.com') {
499+
if ($hostname === 'example.com.') {
500500
return match ($type) {
501501
DNS_SOA => [
502502
[
@@ -511,7 +511,7 @@ static function (RequestInterface $request, array $options): void {
511511
}
512512

513513
// example.net A, AAAA, CNAME
514-
if ($hostname === 'subsubdomain.subdomain.example.com') {
514+
if ($hostname === 'subsubdomain.subdomain.example.com.') {
515515
return match ($type) {
516516
DNS_A => [
517517
[
@@ -540,10 +540,10 @@ static function (RequestInterface $request, array $options): void {
540540
);
541541

542542
$this->assertCount(3, $dnsQueries);
543-
$this->assertContains('example.com' . DNS_SOA, $dnsQueries);
544-
$this->assertContains('subsubdomain.subdomain.example.com' . DNS_A, $dnsQueries);
545-
$this->assertContains('subsubdomain.subdomain.example.com' . DNS_AAAA, $dnsQueries);
543+
$this->assertContains('example.com.' . DNS_SOA, $dnsQueries);
544+
$this->assertContains('subsubdomain.subdomain.example.com.' . DNS_A, $dnsQueries);
545+
$this->assertContains('subsubdomain.subdomain.example.com.' . DNS_AAAA, $dnsQueries);
546546
// CNAME should not be queried if A or AAAA succeeded already
547-
$this->assertNotContains('subsubdomain.subdomain.example.com' . DNS_CNAME, $dnsQueries);
547+
$this->assertNotContains('subsubdomain.subdomain.example.com.' . DNS_CNAME, $dnsQueries);
548548
}
549549
}

0 commit comments

Comments
 (0)