function DestinationTest::testDestination

Same name and namespace in other branches
  1. 8.9.x core/modules/system/tests/src/Functional/Routing/DestinationTest.php \Drupal\Tests\system\Functional\Routing\DestinationTest::testDestination()
  2. 10 core/modules/system/tests/src/Functional/Routing/DestinationTest.php \Drupal\Tests\system\Functional\Routing\DestinationTest::testDestination()
  3. 11.x core/modules/system/tests/src/Functional/Routing/DestinationTest.php \Drupal\Tests\system\Functional\Routing\DestinationTest::testDestination()

Tests that $_GET/$_REQUEST['destination'] only contain internal URLs.

File

core/modules/system/tests/src/Functional/Routing/DestinationTest.php, line 33

Class

DestinationTest
Tests for $_GET['destination'] and $_REQUEST['destination'] validation.

Namespace

Drupal\Tests\system\Functional\Routing

Code

public function testDestination() {
    $http_client = $this->getHttpClient();
    $session = $this->getSession();
    $test_cases = [
        [
            'input' => 'node',
            'output' => 'node',
            'message' => "Standard internal example node path is present in the 'destination' parameter.",
        ],
        [
            'input' => '/example.com',
            'output' => '/example.com',
            'message' => 'Internal path with one leading slash is allowed.',
        ],
        [
            'input' => '//example.com/test',
            'output' => '',
            'message' => 'External URL without scheme is not allowed.',
        ],
        [
            'input' => 'example:test',
            'output' => 'example:test',
            'message' => 'Internal URL using a colon is allowed.',
        ],
        [
            'input' => 'http://example.com',
            'output' => '',
            'message' => 'External URL is not allowed.',
        ],
        [
            'input' => 'javascript:alert(0)',
            'output' => 'javascript:alert(0)',
            'message' => 'JavaScript URL is allowed because it is treated as an internal URL.',
        ],
    ];
    foreach ($test_cases as $test_case) {
        // Test $_GET['destination'].
        $this->drupalGet('system-test/get-destination', [
            'query' => [
                'destination' => $test_case['input'],
            ],
        ]);
        $this->assertSame($test_case['output'], $session->getPage()
            ->getContent(), $test_case['message']);
        // Test $_REQUEST['destination'].
        $post_output = $http_client->request('POST', $this->buildUrl('system-test/request-destination'), [
            'form_params' => [
                'destination' => $test_case['input'],
            ],
        ]);
        $this->assertSame($test_case['output'], (string) $post_output->getBody(), $test_case['message']);
    }
    // Make sure that 404 pages do not populate $_GET['destination'] with
    // external URLs.
    \Drupal::configFactory()->getEditable('system.site')
        ->set('page.404', '/system-test/get-destination')
        ->save();
    $this->drupalGet('http://example.com', [
        'external' => FALSE,
    ]);
    $this->assertSession()
        ->statusCodeEquals(404);
    $this->assertSame(Url::fromRoute('<front>')->toString(), $session->getPage()
        ->getContent(), 'External URL is not allowed on 404 pages.');
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.