From d6c2c2e07f9b0c8341c6b596f0f6744654f99005 Mon Sep 17 00:00:00 2001 From: Stephen Shkardoon Date: Sat, 25 May 2013 18:49:59 +1200 Subject: [PATCH] Fixes #1892 - Stop session hijacking with UA check --- control/Session.php | 18 ++++++++++++++++++ tests/control/SessionTest.php | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/control/Session.php b/control/Session.php index f80363188..17ff7cd66 100644 --- a/control/Session.php +++ b/control/Session.php @@ -137,6 +137,24 @@ class Session { if($data instanceof Session) $data = $data->inst_getAll(); $this->data = $data; + + if (isset($_SERVER['HTTP_USER_AGENT'])) { + $ua = $_SERVER['HTTP_USER_AGENT']; + } else { + $ua = ''; + } + + if (isset($this->data['HTTP_USER_AGENT'])) { + if ($this->data['HTTP_USER_AGENT'] != $ua) { + // Funny business detected! + $this->inst_clearAll(); + + Session::destroy(); + Session::start(); + } + } + + $this->inst_set('HTTP_USER_AGENT', $ua); } /** diff --git a/tests/control/SessionTest.php b/tests/control/SessionTest.php index d3a2e0392..aa7e317c7 100644 --- a/tests/control/SessionTest.php +++ b/tests/control/SessionTest.php @@ -41,7 +41,8 @@ class SessionTest extends SapphireTest { Session::set('Test-2', 'Test-2'); $session = Session::get_all(); - + unset($session['HTTP_USER_AGENT']); + $this->assertEquals($session, array('Test' => 'Test', 'Test-2' => 'Test-2')); } @@ -49,7 +50,9 @@ class SessionTest extends SapphireTest { $s = new Session(array('something' => array('does' => 'exist'))); $s->inst_set('something.does', 'exist'); - $this->assertEquals(array(), $s->inst_changedData()); + $result = $s->inst_changedData(); + unset($result['HTTP_USER_AGENT']); + $this->assertEquals(array(), $result); } /** @@ -59,11 +62,15 @@ class SessionTest extends SapphireTest { $s = new Session(array('something' => array('does' => 'exist'))); $s->inst_clear('something.doesnt.exist'); - $this->assertEquals(array(), $s->inst_changedData()); + $result = $s->inst_changedData(); + unset($result['HTTP_USER_AGENT']); + $this->assertEquals(array(), $result); $s->inst_set('something-else', 'val'); $s->inst_clear('something-new'); - $this->assertEquals(array('something-else' => 'val'), $s->inst_changedData()); + $result = $s->inst_changedData(); + unset($result['HTTP_USER_AGENT']); + $this->assertEquals(array('something-else' => 'val'), $result); } /** @@ -73,7 +80,9 @@ class SessionTest extends SapphireTest { $s = new Session(array('something' => array('does' => 'exist'))); $s->inst_clear('something.does'); - $this->assertEquals(array('something' => array('does' => null)), $s->inst_changedData()); + $result = $s->inst_changedData(); + unset($result['HTTP_USER_AGENT']); + $this->assertEquals(array('something' => array('does' => null)), $result); } public function testNonStandardPath(){ @@ -82,4 +91,20 @@ class SessionTest extends SapphireTest { $this->assertEquals(Config::inst()->get('Session', 'store_path'), ''); } + + public function testUserAgentLockout() { + // Set a user agent + $_SERVER['HTTP_USER_AGENT'] = 'Test Agent'; + + // Generate our session + $s = new Session(array()); + $s->inst_set('val', 123); + + // Change our UA + $_SERVER['HTTP_USER_AGENT'] = 'Fake Agent'; + + // Verify the new session reset our values + $s2 = new Session($s); + $this->assertNotEquals($s2->inst_get('val'), 123); + } }