]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - actions/userauthorization.php
CSRF protection in user registration
[quix0rs-gnu-social.git] / actions / userauthorization.php
index 71ef3cde42a7c7999dcd5ec249bdc57800a8e08b..6208113981d313ec4e87c8570c018ab05f58b3cb 100644 (file)
@@ -23,42 +23,50 @@ require_once(INSTALLDIR.'/lib/omb.php');
 define('TIMESTAMP_THRESHOLD', 300);
 
 class UserauthorizationAction extends Action {
 define('TIMESTAMP_THRESHOLD', 300);
 
 class UserauthorizationAction extends Action {
+
        function handle($args) {
                parent::handle($args);
        function handle($args) {
                parent::handle($args);
-               
+
                if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+                       # CSRF protection
+                       $token = $this->trimmed('token');
+                       if (!$token || $token != common_session_token()) {
+                               $req = $this->get_stored_request();
+                               $this->show_form(_('There was a problem with your session token. Try again, please.'), $req);
+                               return;
+                       }
                        # We've shown the form, now post user's choice
                        $this->send_authorization();
                } else {
                        if (!common_logged_in()) {
                                # Go log in, and then come back
                        # We've shown the form, now post user's choice
                        $this->send_authorization();
                } else {
                        if (!common_logged_in()) {
                                # Go log in, and then come back
-                               common_debug('userauthorization.php - saving URL for returnto');
+                               common_debug('saving URL for returnto', __FILE__);
                                $argsclone = $_GET;
                                unset($argsclone['action']);
                                common_set_returnto(common_local_url('userauthorization', $argsclone));
                                $argsclone = $_GET;
                                unset($argsclone['action']);
                                common_set_returnto(common_local_url('userauthorization', $argsclone));
-                               common_debug('userauthorization.php - redirecting to login');                           
+                               common_debug('redirecting to login', __FILE__);
                                common_redirect(common_local_url('login'));
                                return;
                        }
                        try {
                                # this must be a new request
                                common_redirect(common_local_url('login'));
                                return;
                        }
                        try {
                                # this must be a new request
-                               common_debug('userauthorization.php - getting new request');
+                               common_debug('getting new request', __FILE__);
                                $req = $this->get_new_request();
                                if (!$req) {
                                $req = $this->get_new_request();
                                if (!$req) {
-                                       common_server_error(_t('No request found!'));
+                                       $this->client_error(_('No request found!'));
                                }
                                }
-                               common_debug('userauthorization.php - validating request');
+                               common_debug('validating request', __FILE__);
                                # XXX: only validate new requests, since nonce is one-time use
                                $this->validate_request($req);
                                # XXX: only validate new requests, since nonce is one-time use
                                $this->validate_request($req);
-                               common_debug('userauthorization.php - showing form');
+                               common_debug('showing form', __FILE__);
                                $this->store_request($req);
                                $this->show_form($req);
                        } catch (OAuthException $e) {
                                $this->clear_request();
                                $this->store_request($req);
                                $this->show_form($req);
                        } catch (OAuthException $e) {
                                $this->clear_request();
-                               common_server_error($e->getMessage());
+                               $this->client_error($e->getMessage());
                                return;
                        }
                                return;
                        }
-                       
+
                }
        }
 
                }
        }
 
@@ -72,9 +80,9 @@ class UserauthorizationAction extends Action {
                $bio = $req->get_parameter('omb_listenee_bio');
                $location = $req->get_parameter('omb_listenee_location');
                $avatar = $req->get_parameter('omb_listenee_avatar');
                $bio = $req->get_parameter('omb_listenee_bio');
                $location = $req->get_parameter('omb_listenee_location');
                $avatar = $req->get_parameter('omb_listenee_avatar');
-               
-               common_show_header(_t('Authorize subscription'));
-               common_element('p', NULL, _t('Please check these details to make sure '.
+
+               common_show_header(_('Authorize subscription'));
+               common_element('p', NULL, _('Please check these details to make sure '.
                                                                         'that you want to subscribe to this user\'s notices. '.
                                                                         'If you didn\'t just ask to subscribe to someone\'s notices, '.
                                                                         'click "Cancel".'));
                                                                         'that you want to subscribe to this user\'s notices. '.
                                                                         'If you didn\'t just ask to subscribe to someone\'s notices, '.
                                                                         'click "Cancel".'));
@@ -111,21 +119,22 @@ class UserauthorizationAction extends Action {
                                           $license);
                common_element_end('div');
                common_element_end('div');
                                           $license);
                common_element_end('div');
                common_element_end('div');
-               common_element_start('form', array('method' => 'POST',
+               common_element_start('form', array('method' => 'post',
                                                                                   'id' => 'userauthorization',
                                                                                   'name' => 'userauthorization',
                                                                                   'action' => common_local_url('userauthorization')));
                                                                                   'id' => 'userauthorization',
                                                                                   'name' => 'userauthorization',
                                                                                   'action' => common_local_url('userauthorization')));
-               common_submit('accept', _t('Accept'));
-               common_submit('reject', _t('Reject'));          
+               common_hidden('token', common_session_token());
+               common_submit('accept', _('Accept'));
+               common_submit('reject', _('Reject'));
                common_element_end('form');
                common_show_footer();
        }
                common_element_end('form');
                common_show_footer();
        }
-       
+
        function send_authorization() {
                $req = $this->get_stored_request();
        function send_authorization() {
                $req = $this->get_stored_request();
-               
+
                if (!$req) {
                if (!$req) {
-                       common_user_error(_t('No authorization request!'));
+                       common_user_error(_('No authorization request!'));
                        return;
                }
 
                        return;
                }
 
@@ -133,10 +142,10 @@ class UserauthorizationAction extends Action {
 
                if ($this->arg('accept')) {
                        if (!$this->authorize_token($req)) {
 
                if ($this->arg('accept')) {
                        if (!$this->authorize_token($req)) {
-                               common_server_error(_t('Error authorizing token'));
+                               $this->client_error(_('Error authorizing token'));
                        }
                        if (!$this->save_remote_profile($req)) {
                        }
                        if (!$this->save_remote_profile($req)) {
-                               common_server_error(_t('Error saving remote profile'));
+                               $this->client_error(_('Error saving remote profile'));
                        }
                        if (!$callback) {
                                $this->show_accept_message($req->get_parameter('oauth_token'));
                        }
                        if (!$callback) {
                                $this->show_accept_message($req->get_parameter('oauth_token'));
@@ -188,7 +197,7 @@ class UserauthorizationAction extends Action {
                $consumer_key = $req->get_parameter('oauth_consumer_key');
                $token_field = $req->get_parameter('oauth_token');
                common_debug('consumer key = "'.$consumer_key.'"', __FILE__);
                $consumer_key = $req->get_parameter('oauth_consumer_key');
                $token_field = $req->get_parameter('oauth_token');
                common_debug('consumer key = "'.$consumer_key.'"', __FILE__);
-               common_debug('token field = "'.$token_field.'"', __FILE__);             
+               common_debug('token field = "'.$token_field.'"', __FILE__);
                $rt = new Token();
                $rt->consumer_key = $consumer_key;
                $rt->tok = $token_field;
                $rt = new Token();
                $rt->consumer_key = $consumer_key;
                $rt->tok = $token_field;
@@ -208,23 +217,23 @@ class UserauthorizationAction extends Action {
        }
 
        # XXX: refactor with similar code in finishremotesubscribe.php
        }
 
        # XXX: refactor with similar code in finishremotesubscribe.php
-       
+
        function save_remote_profile(&$req) {
                # FIXME: we should really do this when the consumer comes
        function save_remote_profile(&$req) {
                # FIXME: we should really do this when the consumer comes
-               # back for an access token. If they never do, we've got stuff in a 
+               # back for an access token. If they never do, we've got stuff in a
                # weird state.
                # weird state.
-       
+
                $nickname = $req->get_parameter('omb_listenee_nickname');
                $fullname = $req->get_parameter('omb_listenee_fullname');
                $nickname = $req->get_parameter('omb_listenee_nickname');
                $fullname = $req->get_parameter('omb_listenee_fullname');
-               $profile_url = $req->get_parameter('omb_listenee_profile');             
+               $profile_url = $req->get_parameter('omb_listenee_profile');
                $homepage = $req->get_parameter('omb_listenee_homepage');
                $bio = $req->get_parameter('omb_listenee_bio');
                $location = $req->get_parameter('omb_listenee_location');
                $avatar_url = $req->get_parameter('omb_listenee_avatar');
                $homepage = $req->get_parameter('omb_listenee_homepage');
                $bio = $req->get_parameter('omb_listenee_bio');
                $location = $req->get_parameter('omb_listenee_location');
                $avatar_url = $req->get_parameter('omb_listenee_avatar');
-               
+
                $listenee = $req->get_parameter('omb_listenee');
                $remote = Remote_profile::staticGet('uri', $listenee);
                $listenee = $req->get_parameter('omb_listenee');
                $remote = Remote_profile::staticGet('uri', $listenee);
-               
+
                if ($remote) {
                        $exists = true;
                        $profile = Profile::staticGet($remote->id);
                if ($remote) {
                        $exists = true;
                        $profile = Profile::staticGet($remote->id);
@@ -239,7 +248,7 @@ class UserauthorizationAction extends Action {
 
                $profile->nickname = $nickname;
                $profile->profileurl = $profile_url;
 
                $profile->nickname = $nickname;
                $profile->profileurl = $profile_url;
-               
+
                if ($fullname) {
                        $profile->fullname = $fullname;
                }
                if ($fullname) {
                        $profile->fullname = $fullname;
                }
@@ -252,7 +261,7 @@ class UserauthorizationAction extends Action {
                if ($location) {
                        $profile->location = $location;
                }
                if ($location) {
                        $profile->location = $location;
                }
-               
+
                if ($exists) {
                        $profile->update($orig_profile);
                } else {
                if ($exists) {
                        $profile->update($orig_profile);
                } else {
@@ -291,11 +300,11 @@ class UserauthorizationAction extends Action {
                $sub->subscribed = $remote->id;
                $sub->token = $token->key; # NOTE: request token, not valid for use!
                $sub->created = DB_DataObject_Cast::dateTime(); # current time
                $sub->subscribed = $remote->id;
                $sub->token = $token->key; # NOTE: request token, not valid for use!
                $sub->created = DB_DataObject_Cast::dateTime(); # current time
-               
+
                if (!$sub->insert()) {
                        return FALSE;
                }
                if (!$sub->insert()) {
                        return FALSE;
                }
-               
+
                return TRUE;
        }
 
                return TRUE;
        }
 
@@ -304,11 +313,11 @@ class UserauthorizationAction extends Action {
                copy($url, $temp_filename);
                return $profile->setOriginal($temp_filename);
        }
                copy($url, $temp_filename);
                return $profile->setOriginal($temp_filename);
        }
-       
+
        function show_accept_message($tok) {
        function show_accept_message($tok) {
-               common_show_header(_t('Subscription authorized'));
-               common_element('p', NULL, 
-                                          _t('The subscription has been authorized, but no '.
+               common_show_header(_('Subscription authorized'));
+               common_element('p', NULL,
+                                          _('The subscription has been authorized, but no '.
                                                  'callback URL was passed. Check with the site\'s instructions for '.
                                                  'details on how to authorize the subscription. Your subscription token is:'));
                common_element('blockquote', 'token', $tok);
                                                  'callback URL was passed. Check with the site\'s instructions for '.
                                                  'details on how to authorize the subscription. Your subscription token is:'));
                common_element('blockquote', 'token', $tok);
@@ -316,26 +325,26 @@ class UserauthorizationAction extends Action {
        }
 
        function show_reject_message($tok) {
        }
 
        function show_reject_message($tok) {
-               common_show_header(_t('Subscription rejected'));
-               common_element('p', NULL, 
-                                          _t('The subscription has been rejected, but no '.
+               common_show_header(_('Subscription rejected'));
+               common_element('p', NULL,
+                                          _('The subscription has been rejected, but no '.
                                                  'callback URL was passed. Check with the site\'s instructions for '.
                                                  'details on how to fully reject the subscription.'));
                common_show_footer();
        }
                                                  'callback URL was passed. Check with the site\'s instructions for '.
                                                  'details on how to fully reject the subscription.'));
                common_show_footer();
        }
-       
+
        function store_request($req) {
                common_ensure_session();
                $_SESSION['userauthorizationrequest'] = $req;
        }
        function store_request($req) {
                common_ensure_session();
                $_SESSION['userauthorizationrequest'] = $req;
        }
-       
+
        function clear_request() {
                common_ensure_session();
                unset($_SESSION['userauthorizationrequest']);
        }
        function clear_request() {
                common_ensure_session();
                unset($_SESSION['userauthorizationrequest']);
        }
-       
+
        function get_stored_request() {
        function get_stored_request() {
-               common_ensure_session();                
+               common_ensure_session();
                $req = $_SESSION['userauthorizationrequest'];
                return $req;
        }
                $req = $_SESSION['userauthorizationrequest'];
                return $req;
        }
@@ -344,29 +353,29 @@ class UserauthorizationAction extends Action {
                $req = OAuthRequest::from_request();
                return $req;
        }
                $req = OAuthRequest::from_request();
                return $req;
        }
-       
+
        # Throws an OAuthException if anything goes wrong
        # Throws an OAuthException if anything goes wrong
-       
+
        function validate_request(&$req) {
                # OAuth stuff -- have to copy from OAuth.php since they're
                # all private methods, and there's no user-authentication method
                common_debug('checking version', __FILE__);
                $this->check_version($req);
        function validate_request(&$req) {
                # OAuth stuff -- have to copy from OAuth.php since they're
                # all private methods, and there's no user-authentication method
                common_debug('checking version', __FILE__);
                $this->check_version($req);
-               common_debug('getting datastore', __FILE__);            
+               common_debug('getting datastore', __FILE__);
                $datastore = omb_oauth_datastore();
                common_debug('getting consumer', __FILE__);
                $consumer = $this->get_consumer($datastore, $req);
                $datastore = omb_oauth_datastore();
                common_debug('getting consumer', __FILE__);
                $consumer = $this->get_consumer($datastore, $req);
-               common_debug('getting token', __FILE__);                
+               common_debug('getting token', __FILE__);
                $token = $this->get_token($datastore, $req, $consumer);
                common_debug('checking timestamp', __FILE__);
                $this->check_timestamp($req);
                $token = $this->get_token($datastore, $req, $consumer);
                common_debug('checking timestamp', __FILE__);
                $this->check_timestamp($req);
-               common_debug('checking nonce', __FILE__);               
+               common_debug('checking nonce', __FILE__);
                $this->check_nonce($datastore, $req, $consumer, $token);
                common_debug('checking signature', __FILE__);
                $this->check_signature($req, $consumer, $token);
                $this->check_nonce($datastore, $req, $consumer, $token);
                common_debug('checking signature', __FILE__);
                $this->check_signature($req, $consumer, $token);
-               common_debug('validating omb stuff', __FILE__);         
+               common_debug('validating omb stuff', __FILE__);
                $this->validate_omb($req);
                $this->validate_omb($req);
-               common_debug('done validating', __FILE__);                              
+               common_debug('done validating', __FILE__);
                return true;
        }
 
                return true;
        }
 
@@ -384,7 +393,8 @@ class UserauthorizationAction extends Action {
                if ($version != OMB_VERSION_01) {
                        throw new OAuthException("OpenMicroBlogging version '$version' not supported");
                }
                if ($version != OMB_VERSION_01) {
                        throw new OAuthException("OpenMicroBlogging version '$version' not supported");
                }
-               $user = User::staticGet('uri', $req->get_parameter('omb_listener'));
+               $listener =     $req->get_parameter('omb_listener');
+               $user = User::staticGet('uri', $listener);
                if (!$user) {
                        throw new OAuthException("Listener URI '$listener' not found here");
                }
                if (!$user) {
                        throw new OAuthException("Listener URI '$listener' not found here");
                }
@@ -462,9 +472,9 @@ class UserauthorizationAction extends Action {
                        throw new OAuthException("Invalid callback URL '$callback'");
                }
        }
                        throw new OAuthException("Invalid callback URL '$callback'");
                }
        }
-       
+
        # Snagged from OAuthServer
        # Snagged from OAuthServer
-       
+
        function check_version(&$req) {
                $version = $req->get_parameter("oauth_version");
                if (!$version) {
        function check_version(&$req) {
                $version = $req->get_parameter("oauth_version");
                if (!$version) {
@@ -477,13 +487,13 @@ class UserauthorizationAction extends Action {
        }
 
        # Snagged from OAuthServer
        }
 
        # Snagged from OAuthServer
-       
+
        function get_consumer($datastore, $req) {
                $consumer_key = @$req->get_parameter("oauth_consumer_key");
                if (!$consumer_key) {
                        throw new OAuthException("Invalid consumer key");
                }
        function get_consumer($datastore, $req) {
                $consumer_key = @$req->get_parameter("oauth_consumer_key");
                if (!$consumer_key) {
                        throw new OAuthException("Invalid consumer key");
                }
-               
+
                $consumer = $datastore->lookup_consumer($consumer_key);
                if (!$consumer) {
                        throw new OAuthException("Invalid consumer");
                $consumer = $datastore->lookup_consumer($consumer_key);
                if (!$consumer) {
                        throw new OAuthException("Invalid consumer");
@@ -492,7 +502,7 @@ class UserauthorizationAction extends Action {
        }
 
        # Mostly cadged from OAuthServer
        }
 
        # Mostly cadged from OAuthServer
-       
+
        function get_token($datastore, &$req, $consumer) {/*{{{*/
                $token_field = @$req->get_parameter('oauth_token');
                $token = $datastore->lookup_token($consumer, 'request', $token_field);
        function get_token($datastore, &$req, $consumer) {/*{{{*/
                $token_field = @$req->get_parameter('oauth_token');
                $token = $datastore->lookup_token($consumer, 'request', $token_field);
@@ -501,7 +511,7 @@ class UserauthorizationAction extends Action {
                }
                return $token;
        }
                }
                return $token;
        }
-       
+
        function check_timestamp(&$req) {
                $timestamp = @$req->get_parameter('oauth_timestamp');
                $now = time();
        function check_timestamp(&$req) {
                $timestamp = @$req->get_parameter('oauth_timestamp');
                $now = time();
@@ -520,19 +530,19 @@ class UserauthorizationAction extends Action {
                }
                return true;
        }
                }
                return true;
        }
-       
+
        function check_signature(&$req, $consumer, $token) {
                $signature_method = $this->get_signature_method($req);
        function check_signature(&$req, $consumer, $token) {
                $signature_method = $this->get_signature_method($req);
-               $signature = $req->get_parameter('oauth_signature');    
-               $valid_sig = $signature_method->check_signature($req, 
-                                                                                                               $consumer, 
-                                                                                                               $token, 
+               $signature = $req->get_parameter('oauth_signature');
+               $valid_sig = $signature_method->check_signature($req,
+                                                                                                               $consumer,
+                                                                                                               $token,
                                                                                                                $signature);
                if (!$valid_sig) {
                        throw new OAuthException("Invalid signature");
                }
        }
                                                                                                                $signature);
                if (!$valid_sig) {
                        throw new OAuthException("Invalid signature");
                }
        }
-       
+
        function get_signature_method(&$req) {
                $signature_method = @$req->get_parameter("oauth_signature_method");
                if (!$signature_method) {
        function get_signature_method(&$req) {
                $signature_method = @$req->get_parameter("oauth_signature_method");
                if (!$signature_method) {