From 22c6d2463d80dc5f73e6b8acd1e370da0101826f Mon Sep 17 00:00:00 2001 From: Brian Wolff Date: Tue, 19 Apr 2016 08:55:38 -0400 Subject: [PATCH] [SECURITY] Make $wgBlockDisablesLogin also restrict logged in permissions Otherwise, the user can still do stuff and read pages up until the time their login expires. Issue reported by Multichill Bug: T129738 Change-Id: Ic929a385fa81c27cbc6ac3a0862f51190d3ae993 --- includes/Block.php | 37 ++++++++++++++++++++++++------------- includes/Title.php | 8 +++++++- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/includes/Block.php b/includes/Block.php index 93df004..a62593b 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -961,28 +961,39 @@ class Block { /** * Get/set whether the Block prevents a given action - * @param string $action - * @param bool|null $x - * @return bool + * + * @param string $action Action to check + * @param bool|null $x Value for set, or null to just get value + * @return bool|null Null for unrecognized rights. */ public function prevents( $action, $x = null ) { + global $wgBlockDisablesLogin; + $res = null; switch ( $action ) { case 'edit': # For now... - return true; - + $res = true; + break; case 'createaccount': - return wfSetVar( $this->mCreateAccount, $x ); - + $res = wfSetVar( $this->mCreateAccount, $x ); + break; case 'sendemail': - return wfSetVar( $this->mBlockEmail, $x ); - + $res = wfSetVar( $this->mBlockEmail, $x ); + break; case 'editownusertalk': - return wfSetVar( $this->mDisableUsertalk, $x ); - - default: - return null; + $res = wfSetVar( $this->mDisableUsertalk, $x ); + break; + case 'read': + $res = false; + break; } + if ( !$res && $wgBlockDisablesLogin ) { + // If a block would disable login, then it should + // prevent any action that all users cannot do + $res = User::isEveryoneAllowed( $action ) ? $res : true; + } + + return $res; } /** diff --git a/includes/Title.php b/includes/Title.php index f4a6894..b02c35d 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -2266,13 +2266,18 @@ class Title implements LinkTarget { * @return array List of errors */ private function checkUserBlock( $action, $user, $errors, $rigor, $short ) { + global $wgEmailConfirmToEdit, $wgBlockDisablesLogin; // Account creation blocks handled at userlogin. // Unblocking handled in SpecialUnblock if ( $rigor === 'quick' || in_array( $action, [ 'createaccount', 'unblock' ] ) ) { return $errors; } - global $wgEmailConfirmToEdit; + // Optimize for a very common case + if ( $action === 'read' && !$wgBlockDisablesLogin ) { + return $errors; + } + if ( $wgEmailConfirmToEdit && !$user->isEmailConfirmed() ) { $errors[] = [ 'confirmedittext' ]; @@ -2429,6 +2434,7 @@ class Title implements LinkTarget { $checks = [ 'checkPermissionHooks', 'checkReadPermissions', + 'checkUserBlock', // for wgBlockDisablesLogin ]; # Don't call checkSpecialsAndNSPermissions or checkCSSandJSPermissions # here as it will lead to duplicate error messages. This is okay to do -- 2.0.1