Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ try {
// Current user
$user = ParseUser::getCurrentUser();
```
#### Session Id and Session Fixation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Text looks good 👍 . Should probably add a link to this above 'Verification Emails' in the table of contents and we should be good.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@acinader Can we get this in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think I have just added what you're asking. :).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think he was referring Table of Contents in the ReadME

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

riiight. thanks for spoon feeding me.

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 or anonymous user to registered user.

Changing the PHP session id should have no impact on the contents of the session and state should me maintained for a user that was anonymous and becomes registered.

#### Verification Emails

Expand Down
4 changes: 4 additions & 0 deletions src/Parse/ParseUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
66 changes: 66 additions & 0 deletions tests/Parse/ParseSessionFixationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
namespace Parse\Test;

use Parse\ParseClient;
use Parse\ParseUser;
use Parse\ParseSession;

class ParseSessionFixationTest extends \PHPUnit_Framework_TestCase
{

public static function setUpBeforeClass()
{
Helper::clearClass(ParseUser::$parseClassName);
Helper::clearClass(ParseSession::$parseClassName);
ParseUser::logout();
ParseClient::_unsetStorage();

// indicate we should not use cookies
ini_set("session.use_cookies", 0);
// indicate we can use something other than cookies
ini_set("session.use_only_cookies", 0);
// enable transparent sid support, for url based sessions
ini_set("session.use_trans_sid", 1);
// clear cache control for session pages
ini_set("session.cache_limiter", "");
session_start();
Helper::setUp();
}

public function tearDown()
{
Helper::tearDown();
Helper::clearClass(ParseUser::$parseClassName);
Helper::clearClass(ParseSession::$parseClassName);
ParseUser::logout();
}

public static function tearDownAfterClass()
{
session_destroy();
}

public function testCookieIdChangedForAnonymous()
{
ParseClient::getStorage()->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');
}
}