DestinationTest.php

Same filename in other branches
  1. 9 core/modules/system/tests/src/Functional/Routing/DestinationTest.php
  2. 8.9.x core/modules/system/tests/src/Functional/Routing/DestinationTest.php
  3. 11.x core/modules/system/tests/src/Functional/Routing/DestinationTest.php

Namespace

Drupal\Tests\system\Functional\Routing

File

core/modules/system/tests/src/Functional/Routing/DestinationTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\system\Functional\Routing;

use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;

/**
 * Tests for $_GET['destination'] and $_REQUEST['destination'] validation.
 *
 * Note: This tests basically the same as
 * \Drupal\Tests\Core\EventSubscriber\RedirectResponseSubscriberTest::testSanitizeDestinationForGet
 * \Drupal\Tests\Core\EventSubscriber\RedirectResponseSubscriberTest::testSanitizeDestinationForPost
 * but we want to be absolutely sure it works.
 *
 * @group Routing
 */
class DestinationTest extends BrowserTestBase {
    
    /**
     * {@inheritdoc}
     */
    protected static $modules = [
        'system_test',
    ];
    
    /**
     * {@inheritdoc}
     */
    protected $defaultTheme = 'stark';
    
    /**
     * Tests that $_GET/$_REQUEST['destination'] only contain internal URLs.
     */
    public function testDestination() : void {
        $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.');
    }

}

Classes

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

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