[Pkg-mediawiki-commits] r230 - in mediawiki/lenny/debian: . patches

Jonathan Wiltshire jmw at alioth.debian.org
Fri Dec 17 21:53:40 UTC 2010


Author: jmw
Date: 2010-12-17 21:53:40 +0000 (Fri, 17 Dec 2010)
New Revision: 230

Added:
   mediawiki/lenny/debian/patches/1.15.4-userlogin-security.patch
Modified:
   mediawiki/lenny/debian/changelog
   mediawiki/lenny/debian/patches/series
Log:
Backport fix for CSRF vulnerability in "e-mail me my password", "create account" and "create by e-mail" features of [[Special:Userlogin]]

Modified: mediawiki/lenny/debian/changelog
===================================================================
--- mediawiki/lenny/debian/changelog	2010-09-24 13:17:45 UTC (rev 229)
+++ mediawiki/lenny/debian/changelog	2010-12-17 21:53:40 UTC (rev 230)
@@ -1,3 +1,12 @@
+mediawiki (1:1.12.0-2lenny6) stable; urgency=low
+
+  * Stable upload.
+  * Fixed CSRF vulnerability in "e-mail me my password",
+    "create account" and "create by e-mail" features of
+    [[Special:Userlogin]]
+
+ -- Jonathan Wiltshire <jmw at debian.org>  Fri, 17 Dec 2010 21:51:07 +0000
+
 mediawiki (1:1.12.0-2lenny5) stable-security; urgency=high
 
   * Security upload. Fixes the following issue (CVE-2010-1150):

Added: mediawiki/lenny/debian/patches/1.15.4-userlogin-security.patch
===================================================================
--- mediawiki/lenny/debian/patches/1.15.4-userlogin-security.patch	                        (rev 0)
+++ mediawiki/lenny/debian/patches/1.15.4-userlogin-security.patch	2010-12-17 21:53:40 UTC (rev 230)
@@ -0,0 +1,193 @@
+Description: Fixed CSRF vulnerability in "e-mail me my password",
+ "create account" and "create by e-mail" features of [[Special:Userlogin]]
+Origin: http://www.mediawiki.org/wiki/Special:Code/MediaWiki/66991
+Author: Tim Starling
+Bug: https://bugzilla.wikimedia.org/show_bug.cgi?id=23371
+Last-Update: 2010-12-17
+
+
+--- mediawiki-1.12.0.orig/includes/SpecialUserlogin.php
++++ mediawiki-1.12.0/includes/SpecialUserlogin.php
+@@ -66,7 +66,7 @@
+ 		$this->mAction = $request->getVal( 'action' );
+ 		$this->mRemember = $request->getCheck( 'wpRemember' );
+ 		$this->mLanguage = $request->getText( 'uselang' );
+-		$this->mToken = $request->getVal( 'wpLoginToken' );
++		$this->mToken = ($this->mType == 'signup' ) ? $request->getVal( 'wpCreateaccountToken' ) : $request->getVal( 'wpLoginToken' );
+ 
+ 		if( $wgEnableEmail ) {
+ 			$this->mEmail = $request->getText( 'wpEmail' );
+@@ -234,6 +234,25 @@
+ 			return false;
+ 		}
+ 
++		# Request forgery checks.
++		if ( !self::getCreateaccountToken() ) {
++			self::setCreateaccountToken();
++			$this->mainLoginForm( wfMsg( 'sessionfailure' ) );
++			return false;
++		}
++		
++		# The user didn't pass a createaccount token
++		if ( !$this->mToken ) {
++			$this->mainLoginForm( wfMsg( 'sessionfailure' ) );
++			return false;
++		}
++		
++		# Validate the createaccount token
++		if ( $this->mToken !== self::getCreateaccountToken() ) {
++			$this->mainLoginForm( wfMsg( 'sessionfailure' ) );
++			return false;
++		}
++
+ 		# Check permissions
+ 		if ( !$wgUser->isAllowed( 'createaccount' ) ) {
+ 			$this->userNotPrivilegedMessage();
+@@ -248,7 +267,7 @@
+ 		  $wgUser->inSorbsBlacklist( $ip ) )
+ 		{
+ 			$this->mainLoginForm( wfMsg( 'sorbs_create_account_reason' ) . ' (' . htmlspecialchars( $ip ) . ')' );
+-			return;
++			return false;
+ 		}
+ 
+ 		# Now create a dummy user ($u) and check if it is valid
+@@ -322,6 +341,7 @@
+ 			return false;
+ 		}
+ 
++		self::clearCreateaccountToken();		
+ 		return $this->initUser( $u, false );
+ 	}
+ 
+@@ -540,13 +560,26 @@
+ 			return;
+ 		}
+ 
+-		# Check against blocked IPs
+-		# fixme -- should we not?
++		# Check against blocked IPs so blocked users can't flood admins 
++		# with password resets
+ 		if( $wgUser->isBlocked() ) {
+ 			$this->mainLoginForm( wfMsg( 'blocked-mailpassword' ) );
+ 			return;
+ 		}
+ 
++		# If the user doesn't have a login token yet, set one.
++		if ( !self::getLoginToken() ) {
++			self::setLoginToken();
++			$this->mainLoginForm( wfMsg( 'sessionfailure' ) );
++			return;
++		}
++
++		# If the user didn't pass a login token, tell them we need one
++		if ( !$this->mToken ) {
++			$this->mainLoginForm( wfMsg( 'sessionfailure' ) );
++			return;
++		}
++		
+ 		# Check against the rate limiter
+ 		if( $wgUser->pingLimiter( 'mailpassword' ) ) {
+ 			$wgOut->rateLimited();
+@@ -567,6 +600,12 @@
+ 			return;
+ 		}
+ 
++		# Validate the login token
++		if ( $this->mToken !== self::getLoginToken() ) {
++			$this->mainLoginForm( wfMsg( 'sessionfailure' ) );
++			return;
++		}
++
+ 		# Check against password throttle
+ 		if ( $u->isPasswordReminderThrottled() ) {
+ 			global $wgPasswordReminderResendTime;
+@@ -581,6 +620,7 @@
+ 			$this->mainLoginForm( wfMsg( 'mailerror', $result->getMessage() ) );
+ 		} else {
+ 			$this->mainLoginForm( wfMsg( 'passwordsent', $u->getName() ), 'success' );
++			self::clearLoginToken();
+ 		}
+ 	}
+ 
+@@ -757,11 +797,18 @@
+ 		$template->set( 'canreset', $wgAuth->allowPasswordChange() );
+ 		$template->set( 'remember', $wgUser->getOption( 'rememberpassword' ) or $this->mRemember  );
+ 
+-		if ( !self::getLoginToken() ) {
+-			self::setLoginToken();
++		if ( $this->mType == 'signup' ) {
++			if ( !self::getCreateaccountToken() ) {
++				self::setCreateaccountToken();
++			}
++			$template->set( 'token', self::getCreateaccountToken() );
++		} else {
++			if ( !self::getLoginToken() ) {
++				self::setLoginToken();
++			}
++			$template->set( 'token', self::getLoginToken() );
+ 		}
+-		$template->set( 'token', self::getLoginToken() );
+-
++		
+ 		# Prepare language selection links as needed
+ 		if( $wgLoginLanguageSelector ) {
+ 			$template->set( 'languages', $this->makeLanguageSelector() );
+@@ -820,7 +867,7 @@
+ 	}
+ 	
+ 	/**
+-	 * Generate a new login token and attach it to the current session
++	 * Randomly generate a new login token and attach it to the current session
+ 	 */
+ 	public static function setLoginToken() {
+ 		global $wgRequest;
+@@ -832,12 +879,36 @@
+ 	/**
+ 	 * Remove any login token attached to the current session
+ 	 */
+-	public static  function clearLoginToken() {
++	public static function clearLoginToken() {
+ 		global $wgRequest;
+ 		$wgRequest->setSessionData( 'wsLoginToken', null );
+ 	}
+ 
+ 	/**
++	 * Get the createaccount token from the current session
++	 */
++	public static function getCreateaccountToken() {
++		global $wgRequest;
++		return $wgRequest->getSessionData( 'wsCreateaccountToken' );
++	}
++	
++	/**
++	 * Randomly generate a new createaccount token and attach it to the current session
++	 */
++	public static function setCreateaccountToken() {
++		global $wgRequest;
++		$wgRequest->setSessionData( 'wsCreateaccountToken', User::generateToken() );
++	}
++	
++	/**
++	 * Remove any createaccount token attached to the current session
++	 */
++	public static function clearCreateaccountToken() {
++		global $wgRequest;
++		$wgRequest->setSessionData( 'wsCreateaccountToken', null );
++	}
++
++	/**
+ 	 * @private
+ 	 */
+ 	function cookieRedirectCheck( $type ) {
+--- mediawiki-1.12.0.orig/includes/templates/Userlogin.php
++++ mediawiki-1.12.0/includes/templates/Userlogin.php
+@@ -214,6 +214,7 @@
+ 		</tr>
+ 	</table>
+ <?php if( @$this->haveData( 'uselang' ) ) { ?><input type="hidden" name="uselang" value="<?php $this->text( 'uselang' ); ?>" /><?php } ?>
++<?php if( @$this->haveData( 'token' ) ) { ?><input type="hidden" name="wpCreateaccountToken" value="<?php $this->text( 'token' ); ?>" /><?php } ?>
+ </form>
+ </div>
+ <div id="signupend"><?php $this->msgWiki( 'signupend' ); ?></div>
+ 

Modified: mediawiki/lenny/debian/patches/series
===================================================================
--- mediawiki/lenny/debian/patches/series	2010-09-24 13:17:45 UTC (rev 229)
+++ mediawiki/lenny/debian/patches/series	2010-12-17 21:53:40 UTC (rev 230)
@@ -8,3 +8,4 @@
 CSS-no-CVE_rev-63429.patch
 DataLeakage-no-CVE_rev-63436.patch
 1.15.3-security.patch
+1.15.4-userlogin-security.patch




More information about the Pkg-mediawiki-commits mailing list