You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
4.0 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <?php
  2. namespace p3k\HTTP\Tests;
  3. use p3k\HTTP\Guard;
  4. use PHPUnit\Framework\TestCase;
  5. class GuardTest extends TestCase {
  6. private static function guard(array $dns = [], array $allow = []) {
  7. return new Guard($allow, function($host) use($dns) { return $dns[$host] ?? []; });
  8. }
  9. public static function publicAddresses() {
  10. return [['8.8.8.8'], ['93.184.216.34'], ['2606:4700::1'], ['2001:4860:4860::8888']];
  11. }
  12. public static function nonPublicAddresses() {
  13. return [
  14. ['127.0.0.1'], ['127.8.9.10'], ['10.11.11.80'], ['172.16.0.1'], ['192.168.1.1'], ['169.254.169.254'],
  15. ['100.64.0.1'], ['0.0.0.0'], ['::'], ['::1'], ['fe80::1'], ['fc00::1'], ['fd12:3456::1'],
  16. ['::ffff:127.0.0.1'], ['::ffff:10.0.0.1'], ['64:ff9b::7f00:1'], ['64:ff9b::a00:1'], ['2002:7f00:1::1'], ['2002:a9fe:a9fe::'],
  17. ];
  18. }
  19. #[\PHPUnit\Framework\Attributes\DataProvider('publicAddresses')]
  20. public function testPublicAddresses($address) {
  21. $this->assertTrue(Guard::is_public($address));
  22. }
  23. #[\PHPUnit\Framework\Attributes\DataProvider('nonPublicAddresses')]
  24. public function testNonPublicAddresses($address) {
  25. $this->assertFalse(Guard::is_public($address));
  26. }
  27. public static function blockedUrls() {
  28. return [
  29. ['gopher://127.0.0.1:6379/_SET%20x%201'], ['dict://127.0.0.1:6379/info'], ['file:///etc/passwd'],
  30. ['ftp://example.com/'], ['ldap://example.com/'], ['javascript:alert(1)'], ['/relative'], ['https://'],
  31. ['http://127.0.0.1/'], ['http://localhost.example/'], ['http://[::1]/'], ['http://[::ffff:127.0.0.1]/'],
  32. ['http://2130706433/'], ['http://0x7f000001/'], ['http://0177.0.0.1/'], ['http://127.1/'], ['http://0/'],
  33. ['http://169.254.169.254/latest/meta-data/'], ['http://mixed.example/'],
  34. ];
  35. }
  36. #[\PHPUnit\Framework\Attributes\DataProvider('blockedUrls')]
  37. public function testBlockedUrls($url) {
  38. $result = self::guard(['localhost.example' => ['127.0.0.1'], 'mixed.example' => ['93.184.216.34', '10.0.0.1']])->check($url);
  39. $this->assertSame('blocked_url', $result['error'] ?? null, $url);
  40. }
  41. public function testPublicHostIsAllowedWithItsAddresses() {
  42. $result = self::guard(['example.com' => ['93.184.216.34', '2606:2800:220:1::']])->check('https://Example.com/path');
  43. $this->assertSame(['host' => 'example.com', 'port' => 443, 'addresses' => ['93.184.216.34', '2606:2800:220:1::']], $result);
  44. }
  45. public function testExplicitPort() {
  46. $result = self::guard(['example.com' => ['93.184.216.34']])->check('http://example.com:8080/');
  47. $this->assertSame(8080, $result['port']);
  48. }
  49. public function testUnresolvableHost() {
  50. $this->assertSame('dns_error', self::guard()->check('https://nowhere.example/')['error']);
  51. }
  52. public function testAllowedHost() {
  53. $guard = self::guard(['dev.example' => ['10.11.11.80']], ['dev.example']);
  54. $this->assertSame(['10.11.11.80'], $guard->check('https://dev.example/')['addresses']);
  55. $this->assertArrayHasKey('error', $guard->check('https://other.example/'));
  56. }
  57. public function testAllowedRange() {
  58. $guard = self::guard(['dev.example' => ['10.11.11.80'], 'db.example' => ['10.11.12.5']], ['10.11.11.0/24']);
  59. $this->assertArrayNotHasKey('error', $guard->check('https://dev.example/'));
  60. $this->assertArrayHasKey('error', $guard->check('https://db.example/'));
  61. }
  62. public function testAllowedSingleAddress() {
  63. $guard = self::guard([], ['127.0.0.1', '::1']);
  64. $this->assertArrayNotHasKey('error', $guard->check('http://127.0.0.1:8000/'));
  65. $this->assertArrayNotHasKey('error', $guard->check('http://[::1]:8000/'));
  66. $this->assertArrayHasKey('error', $guard->check('http://127.0.0.2/'));
  67. }
  68. public function testInCidr() {
  69. $this->assertTrue(Guard::in_cidr('10.11.11.80', '10.11.11.0/24'));
  70. $this->assertFalse(Guard::in_cidr('10.11.12.80', '10.11.11.0/24'));
  71. $this->assertTrue(Guard::in_cidr('10.11.11.80', '10.8.0.0/13'));
  72. $this->assertTrue(Guard::in_cidr('fd00::1', 'fc00::/7'));
  73. $this->assertFalse(Guard::in_cidr('10.0.0.1', 'fc00::/7'));
  74. }
  75. }