Skip to content

Commit e2ed51f

Browse files
committed
Fix mismatched URL comparisions in SecurityComponent.
When SecurityComponent was updated to use new request methods, I forgot to take into account base URL paths. In order to get those applied, we can use Router::url(). This ensures we get the same urls that FormHelper creates. I've also fixed an issue where if the session hadn't already been started secured forms would fail as session_id() would return '' instead of the actual session id. Refs #11932
1 parent 887dc4d commit e2ed51f

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

src/Controller/Component/SecurityComponent.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Cake\Event\Event;
2323
use Cake\Http\Exception\BadRequestException;
2424
use Cake\Http\ServerRequest;
25+
use Cake\Routing\Router;
2526
use Cake\Utility\Hash;
2627
use Cake\Utility\Security;
2728

@@ -378,14 +379,21 @@ protected function _validToken(Controller $controller)
378379
*/
379380
protected function _hashParts(Controller $controller)
380381
{
381-
$fieldList = $this->_fieldsList($controller->request->getData());
382-
$unlocked = $this->_sortedUnlocked($controller->request->getData());
382+
$request = $controller->getRequest();
383+
384+
// Start the session to ensure we get the correct session id.
385+
$session = $request->getSession();
386+
$session->start();
387+
388+
$data = $request->getData();
389+
$fieldList = $this->_fieldsList($data);
390+
$unlocked = $this->_sortedUnlocked($data);
383391

384392
return [
385-
$controller->request->getRequestTarget(),
393+
Router::url($request->getRequestTarget()),
386394
serialize($fieldList),
387395
$unlocked,
388-
session_id(),
396+
$session->id()
389397
];
390398
}
391399

tests/TestCase/Controller/Component/SecurityComponentTest.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Cake\Event\Event;
2222
use Cake\Http\ServerRequest;
2323
use Cake\Http\Session;
24+
use Cake\Routing\Router;
2425
use Cake\TestSuite\TestCase;
2526
use Cake\Utility\Security;
2627

@@ -189,7 +190,7 @@ public function tearDown()
189190
unset($this->Controller);
190191
}
191192

192-
public function validatePost($expectedException = null, $expectedExceptionMessage = null)
193+
public function validatePost($expectedException = 'SecurityException', $expectedExceptionMessage = null)
193194
{
194195
try {
195196
return $this->Controller->Security->validatePost($this->Controller);
@@ -744,6 +745,37 @@ public function testValidatePostSimple()
744745
$this->assertTrue($result);
745746
}
746747

748+
/**
749+
* test validatePost uses full URL
750+
*
751+
* @return void
752+
* @triggers Controller.startup $this->Controller
753+
*/
754+
public function testValidatePostSubdirectory()
755+
{
756+
// set the base path.
757+
$this->Controller->request = $this->Controller->request
758+
->withAttribute('base', 'subdir')
759+
->withAttributE('webroot', 'subdir/');
760+
Router::pushRequest($this->Controller->request);
761+
762+
$event = new Event('Controller.startup', $this->Controller);
763+
$this->Security->startup($event);
764+
765+
// Differs from testValidatePostSimple because of base url
766+
$fields = 'cc9b6af3f33147235ae8f8037b0a71399a2425f2%3A';
767+
$unlocked = '';
768+
$debug = '';
769+
770+
$this->Controller->request = $this->Controller->request->withParsedBody([
771+
'Model' => ['username' => '', 'password' => ''],
772+
'_Token' => compact('fields', 'unlocked', 'debug')
773+
]);
774+
775+
$result = $this->validatePost();
776+
$this->assertTrue($result);
777+
}
778+
747779
/**
748780
* testValidatePostComplex method
749781
*

0 commit comments

Comments
 (0)