diff --git a/CHANGELOG.md b/CHANGELOG.md index 60ac4141..caaae387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ - Adds Parse Server Health Check (#366) - Adds the ability to upgrade to a revocable session (#368) - Adds ability to Request Verification Emails (#369) -- Adds the ability to set/save in `ParseConfig` (#371) +- Adds the ability to set/save in `ParseConfig` (#371) - Adds `ParseLogs` (#370) - Adds `ParseAudience` (#372) - Adds jobs to `ParseCloud` (#373) @@ -40,7 +40,7 @@ - Updates to make the sdk friendly with `phpdoc` - Added **Getting Started** section to README -- Removed the default server and mount path for `api.parse.com` +- Removed the default server and mount path for `api.parse.com` - Setup `phpdoc` style enforcing and autodeploy from most recent `master` for our [api ref](http://parseplatform.org/parse-php-sdk/namespaces/Parse.html) - **jms/serializer** pinned to **1.7.1** for testing as mentioned in #336 (for phpdoc) - Added **ParsePolygon** type and `polygonContains` to **ParseQuery** (thanks to [Diamond Lewis](https://github.com/dplewis)) @@ -266,4 +266,4 @@ - Updated visibility of `ParseObject::_isDirty` to `protected` (thanks to [Fosco Marotto](https://github.com/gfosco)) ### 1.0.0 -- Initial release! (thanks to [Fosco Marotto](https://github.com/gfosco)) \ No newline at end of file +- Initial release! (thanks to [Fosco Marotto](https://github.com/gfosco)) diff --git a/README.md b/README.md index 56a40f1d..5174f79b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Please note that this documentation contains the latest changes that may as of y - [Use Declarations](#use-declarations) - [Parse Objects](#parse-objects) - [Users](#users) + - [Session Id and Session Fixation](#session-id-and-session-fixation) - [Verification Emails](#verification-emails) - [ACLs/Security](#acls) - [Queries](#queries) @@ -288,6 +289,10 @@ try { // Current user $user = ParseUser::getCurrentUser(); ``` +#### Session Id and Session Fixation +In an attempt to avoid [session fixation exploits](https://www.owasp.org/index.php/Session_fixation), the PHP SDK will call [`session_regenerate_id()`](http://php.net/manual/en/function.session-regenerate-id.php) when a session's permissions are elevated (since 1.5.0). In practice this means that `session_regenerate_id()` will be called when a session goes from no user to anonymous user or from no user / anonymous user to registered user. + +Changing the PHP session id should have no impact on the contents of the session and state should be maintained for a user that was anonymous and becomes registered. #### Verification Emails diff --git a/src/Parse/ParseUser.php b/src/Parse/ParseUser.php index e559b176..57b35c07 100644 --- a/src/Parse/ParseUser.php +++ b/src/Parse/ParseUser.php @@ -500,6 +500,10 @@ protected function handleSaveResult($makeCurrent = false) unset($this->serverData['sessionToken']); } if ($makeCurrent) { + if (session_id()) { + // see: https://www.owasp.org/index.php/Session_fixation + session_regenerate_id(); + } static::$currentUser = $this; static::saveCurrentUser(); } diff --git a/tests/Parse/ParseSessionFixationTest.php b/tests/Parse/ParseSessionFixationTest.php new file mode 100644 index 00000000..93641c63 --- /dev/null +++ b/tests/Parse/ParseSessionFixationTest.php @@ -0,0 +1,66 @@ +set('test', 'hi'); + $noUserSessionId = session_id(); + $user = ParseUser::loginWithAnonymous(); + $anonymousSessionId = session_id(); + $this->assertNotEquals($noUserSessionId, $anonymousSessionId); + $this->assertEquals(ParseClient::getStorage()->get('test'), 'hi'); + } + + public function testCookieIdChangedForAnonymousToRegistered() + { + $user = ParseUser::loginWithAnonymous(); + $anonymousSessionId = session_id(); + ParseClient::getStorage()->set('test', 'hi'); + $user->setUsername('testy'); + $user->setPassword('testy'); + $user->save(); + $user->login('testy', 'testy'); + $registeredSessionId = session_id(); + $this->assertNotEquals($anonymousSessionId, $registeredSessionId); + $this->assertEquals(ParseClient::getStorage()->get('test'), 'hi'); + } +}