DestinationTest.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <?php
  2. namespace Drupal\system\Tests\Routing;
  3. use Drupal\Core\Url;
  4. use Drupal\simpletest\WebTestBase;
  5. /**
  6. * Tests for $_GET['destination'] and $_REQUEST['destination'] validation.
  7. *
  8. * Note: This tests basically the same as
  9. * \Drupal\Tests\Core\EventSubscriber\RedirectResponseSubscriberTest::testSanitizeDestinationForGet
  10. * \Drupal\Tests\Core\EventSubscriber\RedirectResponseSubscriberTest::testSanitizeDestinationForPost
  11. * but we want to be absolutely sure it works.
  12. *
  13. * @group Routing
  14. */
  15. class DestinationTest extends WebTestBase {
  16. /**
  17. * {@inheritdoc}
  18. */
  19. public static $modules = ['system_test'];
  20. /**
  21. * Tests that $_GET/$_REQUEST['destination'] only contain internal URLs.
  22. */
  23. public function testDestination() {
  24. $test_cases = [
  25. [
  26. 'input' => 'node',
  27. 'output' => 'node',
  28. 'message' => "Standard internal example node path is present in the 'destination' parameter.",
  29. ],
  30. [
  31. 'input' => '/example.com',
  32. 'output' => '/example.com',
  33. 'message' => 'Internal path with one leading slash is allowed.',
  34. ],
  35. [
  36. 'input' => '//example.com/test',
  37. 'output' => '',
  38. 'message' => 'External URL without scheme is not allowed.',
  39. ],
  40. [
  41. 'input' => 'example:test',
  42. 'output' => 'example:test',
  43. 'message' => 'Internal URL using a colon is allowed.',
  44. ],
  45. [
  46. 'input' => 'http://example.com',
  47. 'output' => '',
  48. 'message' => 'External URL is not allowed.',
  49. ],
  50. [
  51. 'input' => 'javascript:alert(0)',
  52. 'output' => 'javascript:alert(0)',
  53. 'message' => 'Javascript URL is allowed because it is treated as an internal URL.',
  54. ],
  55. ];
  56. foreach ($test_cases as $test_case) {
  57. // Test $_GET['destination'].
  58. $this->drupalGet('system-test/get-destination', ['query' => ['destination' => $test_case['input']]]);
  59. $this->assertIdentical($test_case['output'], $this->getRawContent(), $test_case['message']);
  60. // Test $_REQUEST['destination'].
  61. $post_output = $this->drupalPost('system-test/request-destination', '*', ['destination' => $test_case['input']]);
  62. $this->assertIdentical($test_case['output'], $post_output, $test_case['message']);
  63. }
  64. // Make sure that 404 pages do not populate $_GET['destination'] with
  65. // external URLs.
  66. \Drupal::configFactory()->getEditable('system.site')->set('page.404', '/system-test/get-destination')->save();
  67. $this->drupalGet('http://example.com', ['external' => FALSE]);
  68. $this->assertResponse(404);
  69. $this->assertIdentical(Url::fromRoute('<front>')->toString(), $this->getRawContent(), 'External URL is not allowed on 404 pages.');
  70. }
  71. }