Skip to content

Commit 1c43171

Browse files
authored
Merge pull request #17 from kiwicom/prevent-localhost
Improve localhost binding
2 parents 3fbf6b0 + cb4e56c commit 1c43171

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
🛠️️ CLI tool to easily bind localhost network interface with additional IP and ensure matching record in /etc/hosts.
44

5+
> [!WARNING]
6+
> **This tool should only be used in local environments and should not be used in production.**
7+
>
8+
> **It is crucial to use this tool only on projects (configs) under your control as it can seriously compromise your /etc/hosts file.**
9+
510
This is a helper tool to be installed via `composer global` to machines where the localhost deployment process of
611
Docker composition (via `docker-compose.yaml`) is prepared in a way that it binds the ports on IP from localhost subnet block and multiple of such
712
compositions should be allowed to run in parallel (differentiated by the IP).

src/Config/Config.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Kiwicom\Loopbind\Config;
44

55
use JsonSerializable;
6+
use Kiwicom\Loopbind\Helpers\IPHelpers;
67
use function array_map;
78
use function filter_var;
89
use function is_array;
@@ -36,8 +37,11 @@ public function __construct(
3637
if (is_array($hostname)) {
3738
array_map(fn (string $host): bool => filter_var($host, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) === false ?
3839
throw new \Kiwicom\Loopbind\Exceptions\InvalidHostnameException("Value `{$host}` is not valid hostname.") : true, $hostname);
40+
41+
array_map(fn (string $hostname): bool => IPHelpers::isForbiddenDomain($hostname) ?
42+
throw new \Kiwicom\Loopbind\Exceptions\InvalidHostnameException("Hostname `{$hostname}` is forbidden by this tool.") : true, $hostname);
3943
}
40-
if ($hostname === 'localhost') {
44+
if (is_string($hostname) && IPHelpers::isForbiddenDomain($hostname)) {
4145
throw new \Kiwicom\Loopbind\Exceptions\InvalidHostnameException("Hostname `{$hostname}` is forbidden by this tool.");
4246
}
4347

src/Helpers/IPHelpers.php

+27
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,31 @@ public static function findRandomFreeLocalIP(): string
3434
}
3535
throw new UnableToFindUnreferencedIPAddressException();
3636
}
37+
38+
/**
39+
* Returns true iff the given URL is a forbidden domain
40+
* @param string $url
41+
* @return bool
42+
*/
43+
public static function isForbiddenDomain(string $url): bool
44+
{
45+
$url = mb_strtolower($url);
46+
$forbidden = [
47+
'localhost',
48+
'localhost4',
49+
'localhost6',
50+
'localhost.localdomain',
51+
'localhost4.localdomain4',
52+
'localhost6.localdomain6',
53+
'ip6-localhost',
54+
'ip6-loopback',
55+
'ip6-localnet',
56+
'ip6-mcastprefix',
57+
'ip6-allnodes',
58+
'ip6-allrouters',
59+
'ip6-allhosts',
60+
'broadcasthost'
61+
];
62+
return in_array($url, $forbidden, true);
63+
}
3764
}

tests/Config/ConfigTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,10 @@ public function testInvalidHostname2(): void
4444
$this->expectException(\Kiwicom\Loopbind\Exceptions\InvalidHostnameException::class);
4545
new Config('127.0.0.12', 'č.test');
4646
}
47+
48+
public function testInvalidHostname3(): void
49+
{
50+
$this->expectException(\Kiwicom\Loopbind\Exceptions\InvalidHostnameException::class);
51+
new Config('127.0.0.12', ['localhost']);
52+
}
4753
}

0 commit comments

Comments
 (0)