Commit 7298c336 authored by catch's avatar catch

Issue #2512452 by dawehner, pwolanin, alexpott, fnqgpc: Confirm form cancel...

Issue #2512452 by dawehner, pwolanin, alexpott, fnqgpc: Confirm form cancel button can lead to external domain
parent e044adb0
...@@ -30,14 +30,20 @@ class ConfirmFormHelper { ...@@ -30,14 +30,20 @@ class ConfirmFormHelper {
public static function buildCancelLink(ConfirmFormInterface $form, Request $request) { public static function buildCancelLink(ConfirmFormInterface $form, Request $request) {
// Prepare cancel link. // Prepare cancel link.
$query = $request->query; $query = $request->query;
$url = NULL;
// If a destination is specified, that serves as the cancel link. // If a destination is specified, that serves as the cancel link.
if ($query->has('destination')) { if ($query->has('destination')) {
$options = UrlHelper::parse($query->get('destination')); $options = UrlHelper::parse($query->get('destination'));
// @todo Revisit this in https://www.drupal.org/node/2418219. // @todo Revisit this in https://www.drupal.org/node/2418219.
$url = Url::fromUserInput('/' . ltrim($options['path'], '/'), $options); try {
$url = Url::fromUserInput('/' . ltrim($options['path'], '/'), $options);
}
catch (\InvalidArgumentException $e) {
// Suppress the exception and fall back to the form's cancel url.
}
} }
// Check for a route-based cancel link. // Check for a route-based cancel link.
else { if (!$url) {
$url = $form->getCancelUrl(); $url = $form->getCancelUrl();
} }
......
...@@ -426,6 +426,10 @@ protected static function fromInternalUri(array $uri_parts, array $options) { ...@@ -426,6 +426,10 @@ protected static function fromInternalUri(array $uri_parts, array $options) {
} }
// Remove the leading slash. // Remove the leading slash.
$uri_parts['path'] = substr($uri_parts['path'], 1); $uri_parts['path'] = substr($uri_parts['path'], 1);
if (UrlHelper::isExternal($uri_parts['path'])) {
throw new \InvalidArgumentException(SafeMarkup::format('The internal path component "@path" is external. You are not allowed to specify an external URL together with internal:/.', ['@path' => $uri_parts['path']]));
}
} }
$url = \Drupal::pathValidator() $url = \Drupal::pathValidator()
......
...@@ -62,6 +62,11 @@ public function testConfirmFormWithExternalDestination() { ...@@ -62,6 +62,11 @@ public function testConfirmFormWithExternalDestination() {
$this->assertCancelLinkUrl(Url::fromUri('internal:/node')); $this->assertCancelLinkUrl(Url::fromUri('internal:/node'));
$this->drupalGet('form-test/confirm-form', array('query' => array('destination' => 'http://example.com'))); $this->drupalGet('form-test/confirm-form', array('query' => array('destination' => 'http://example.com')));
$this->assertCancelLinkUrl(Url::fromRoute('form_test.route8')); $this->assertCancelLinkUrl(Url::fromRoute('form_test.route8'));
$this->drupalGet('form-test/confirm-form', array('query' => array('destination' => '<front>')));
$this->assertCancelLinkUrl(Url::fromRoute('<front>'));
// Other invalid destinations, should fall back to the form default.
$this->drupalGet('form-test/confirm-form', array('query' => array('destination' => '/http://example.com')));
$this->assertCancelLinkUrl(Url::fromRoute('form_test.route8'));
} }
/** /**
......
...@@ -729,20 +729,22 @@ public function testFromInvalidInternalUri($path) { ...@@ -729,20 +729,22 @@ public function testFromInvalidInternalUri($path) {
public function providerFromInvalidInternalUri() { public function providerFromInvalidInternalUri() {
return [ return [
// Normal paths without a leading slash. // Normal paths without a leading slash.
['kittens'], 'normal_path0' => ['kittens'],
['kittens/bengal'], 'normal_path1' => ['kittens/bengal'],
// Path without a leading slash containing a fragment. // Path without a leading slash containing a fragment.
['kittens#feeding'], 'fragment' => ['kittens#feeding'],
// Path without a leading slash containing a query string. // Path without a leading slash containing a query string.
['kittens?page=1000'], 'without_leading_slash_query' => ['kittens?page=1000'],
// Paths with various token formats but no leading slash. // Paths with various token formats but no leading slash.
['[duckies]'], 'path_with_tokens0' => ['[duckies]'],
['%bunnies'], 'path_with_tokens1' => ['%bunnies'],
['{{ puppies }}'], 'path_with_tokens2' => ['{{ puppies }}'],
// Disallowed characters in the authority (host name) that are valid // Disallowed characters in the authority (host name) that are valid
// elsewhere in the path. // elsewhere in the path.
['(:;2&+h^'], 'disallowed_hostname_chars0' => ['(:;2&+h^'],
['AKI@&hO@'], 'disallowed_hostname_chars1' => ['AKI@&hO@'],
// Leading slash with a domain.
'leading_slash_with_domain' => ['/http://example.com'],
]; ];
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment