diff --git a/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php b/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php new file mode 100644 index 0000000..628ca37 --- /dev/null +++ b/core/modules/system/src/Tests/Session/MultipleAuthenticationSessionTest.php @@ -0,0 +1,100 @@ +user = $this->drupalCreateUser(array('administer site configuration')); + } + + /** + * Check that a basic authentication session does not leak. + * + * Regression test for a bug that caused a session initiated by basic + * authentication to persist over subsequent unauthorized requests. + * + * @see https://www.drupal.org/node/2468873 + */ + public function testSessionFromBasicAuthenticationDoesNotLeak() { + // This page is authorized through basic_auth only, not cookie. + $url = Url::fromRoute('session_test.get_session'); + + // Test that the route is not accessible as an anonymous user. + $this->drupalGet($url); + $this->assertResponse(401, 'An anonymous user cannot access a route protected with basic authentication.'); + + // We should be able to access the route with basic authentication. + $this->basicAuthGet($url); + $this->assertResponse(200, 'A route protected with basic authentication can be accessed by an authenticated user.'); + + // If we now try to access the page again without basic authentication then + // we should no longer be authorized. + $this->drupalGet($url); + $this->assertResponse(401, 'A subsequent request to the same route without basic authentication is not authorized.'); + } + + /** + * Retrieves a Drupal path or an absolute path using basic authentication. + * + * @param \Drupal\Core\Url|string $path + * Drupal path or URL to load into the internal browser. + * @param array $options + * Options to be forwarded to the url generator. + * @param array $headers + * An array containing additional HTTP request headers, each formatted as + * "name: value". + * + * @return string + * The retrieved HTML string, also available as $this->getRawContent(). + */ + protected function basicAuthGet($path, array $options = array(), array $headers = array()) { + // Set up Curl to use basic authentication with the test user's credentials. + $this->additionalCurlOptions = [ + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => $this->user->getUsername() . ':' . $this->user->pass_raw, + ]; + + $output = $this->drupalGet($path, $options, $headers); + + // Reset the Curl options. + $this->additionalCurlOptions = [ + CURLOPT_HTTPAUTH => NULL, + CURLOPT_USERPWD => NULL, + ]; + + return $output; + } + +} diff --git a/core/modules/system/tests/modules/session_test/session_test.routing.yml b/core/modules/system/tests/modules/session_test/session_test.routing.yml index fce0fc9..6dbf85c 100644 --- a/core/modules/system/tests/modules/session_test/session_test.routing.yml +++ b/core/modules/system/tests/modules/session_test/session_test.routing.yml @@ -89,3 +89,13 @@ session_test.trace_handler: _controller: '\Drupal\session_test\Controller\SessionTestController::traceHandler' requirements: _access: 'TRUE' + +session_test.get_session: + path: '/session-test/get-session' + defaults: + _title: 'Get session information using basic authentication' + _controller: '\Drupal\session_test\Controller\SessionTestController::getSession' + options: + _auth: ['basic_auth'] + requirements: + _permission: 'administer site configuration' diff --git a/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php b/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php index 4437743..c87ef63 100644 --- a/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php +++ b/core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php @@ -162,4 +162,15 @@ public function traceHandler() { return new JsonResponse($trace); } + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + * A response object containing the session values and the user ID. + */ + public function getSession(Request $request) { + return new JsonResponse(['session' => $request->getSession()->all(), 'user' => $this->currentUser()->id()]); + } + }