From f79f44801cfd76b7e9e4cbfb94917bc8b395a886 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 29 Sep 2010 15:52:18 -0700 Subject: [PATCH] - Lookup anon profiles by ID (safer because they are guranteed to be unique) and probably faster - Obfuscate the anonymous user session token to make it hard to figure out the profile ID --- plugins/AnonymousFave/AnonymousFavePlugin.php | 56 ++++++++++++------- plugins/AnonymousFave/anondisfavor.php | 10 +--- plugins/AnonymousFave/anonfavor.php | 9 +-- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/plugins/AnonymousFave/AnonymousFavePlugin.php b/plugins/AnonymousFave/AnonymousFavePlugin.php index 41542c8493..264cad1748 100644 --- a/plugins/AnonymousFave/AnonymousFavePlugin.php +++ b/plugins/AnonymousFave/AnonymousFavePlugin.php @@ -151,7 +151,7 @@ class AnonymousFavePlugin extends Plugin { if (!common_logged_in()) { - $profile = $this->getAnonProfile(); + $profile = AnonymousFavePlugin::getAnonProfile(); if (!empty($profile)) { if ($profile->hasFave($item->notice)) { $disfavor = new AnonDisFavorForm($item->out, $item->notice); @@ -207,42 +207,58 @@ class AnonymousFavePlugin extends Plugin { // Get the anon user's IP, and turn it into a nickname list($proxy, $ip) = common_client_ip(); - // IP + time + random number should avoid collisions - $nickname = 'anonymous-' . $ip . '-' . time() . '-' . common_good_rand(5); + + // IP + time + random number should help to avoid collisions + $baseNickname = $ip . '-' . time() . '-' . common_good_rand(5); $profile = new Profile(); - $profile->nickname = $nickname; + $profile->nickname = $baseNickname; $id = $profile->insert(); - if (!empty($id)) { - common_log( - LOG_INFO, - "AnonymousFavePlugin - created profile for anonymous user from IP: " - . $ip - . ', nickname = ' - . $nickname - ); + if (!$id) { + throw new ServerException(_m("Couldn't create anonymous user session")); } + // Stick the Profile ID into the nickname + $orig = clone($profile); + + $profile->nickname = 'anon-' . $id . '-' . $baseNickname; + $result = $profile->update($orig); + + if (!$result) { + throw new ServerException(_m("Couldn't create anonymous user session")); + } + + common_log( + LOG_INFO, + "AnonymousFavePlugin - created profile for anonymous user from IP: " + . $ip + . ', nickname = ' + . $profile->nickname + ); + return $profile; } - function getAnonProfile() { + static function getAnonProfile() { - $anon = $_SESSION['anon_nickname']; + $token = $_SESSION['anon_token']; + $anon = base64_decode($token); $profile = null; - if (!empty($anon)) { - $profile = Profile::staticGet('nickname', $anon); + if (!empty($anon) && substr($anon, 0, 5) == 'anon-') { + $parts = explode('-', $anon); + $id = $parts[1]; + // Do Profile lookup by ID instead of nickname for safety/performance + $profile = Profile::staticGet('id', $id); } else { $profile = $this->createAnonProfile(); - $_SESSION['anon_nickname'] = $profile->nickname; + // Obfuscate so it's hard to figure out the Profile ID + $_SESSION['anon_token'] = base64_encode($profile->nickname); } - if (!empty($profile)) { - return $profile; - } + return $profile; } /** diff --git a/plugins/AnonymousFave/anondisfavor.php b/plugins/AnonymousFave/anondisfavor.php index 9fd56fdc32..f39d5a7780 100644 --- a/plugins/AnonymousFave/anondisfavor.php +++ b/plugins/AnonymousFave/anondisfavor.php @@ -54,15 +54,7 @@ class AnonDisfavorAction extends RedirectingAction { parent::handle($args); - $anon = $_SESSION['anon_nickname']; - - $profile = Profile::staticGet('nickname', $anon); - - if (empty($profile)) { - common_debug( - "AnonDisFavorAction - Anon user tried to disfave a notice but doesn't have a profile." - ); - } + $profile = AnonymousFavePlugin::getAnonProfile(); if (empty($profile) || $_SERVER['REQUEST_METHOD'] != 'POST') { $this->clientError( diff --git a/plugins/AnonymousFave/anonfavor.php b/plugins/AnonymousFave/anonfavor.php index c972f202e4..58570ced9a 100644 --- a/plugins/AnonymousFave/anonfavor.php +++ b/plugins/AnonymousFave/anonfavor.php @@ -54,14 +54,7 @@ class AnonFavorAction extends RedirectingAction { parent::handle($args); - $anon = $_SESSION['anon_nickname']; - $profile = Profile::staticGet('nickname', $anon); - - if (empty($profile)) { - common_debug( - "AnonFavorAction - Anon user tried to fave a notice but doesn't have a profile." - ); - } + $profile = AnonymousFavePlugin::getAnonProfile(); if (empty($profile) || $_SERVER['REQUEST_METHOD'] != 'POST') { $this->clientError(