Deprecate $wgPasswordSenderName
authortheopolisme <theopolismewiki@gmail.com>
Tue, 31 Dec 2013 06:12:09 +0000 (00:12 -0600)
committertheopolisme <theopolismewiki@gmail.com>
Wed, 1 Jan 2014 14:27:59 +0000 (08:27 -0600)
The sender name for system mailings can now be configured
locally by modifying the system message "emailsender". The
new default sender name is simply "{{SITENAME}}". Added to
release notes.

Also modify UserMailer to strip CR/LF linebreaks from header
values to prevent mail header injection now that the sender
name can be modified.

Bug: 32770
Change-Id: Ibfd28cd181365c8c0b5f3e8ffe8f5de8c89844a3

RELEASE-NOTES-1.23
includes/DefaultSettings.php
includes/User.php
includes/UserMailer.php
includes/specials/SpecialEmailuser.php
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php
maintenance/language/messageTypes.inc
maintenance/language/messages.inc

index a7ae161..216ab67 100644 (file)
@@ -26,6 +26,8 @@ production.
   now enabled by default.
 * $wgLBFactoryConf: Class names have had underscores removed. The configuration
   should be updated if LBFactory_Simple or LBFactory_Multi is configured.
+* $wgPasswordSenderName has been deprecated. To set a custom mailer name,
+  the system message 'emailsender' should be modified (default: "{{SITENAME}}").
 
 === New features in 1.23 ===
 * ResourceLoader can utilize the Web Storage API to cache modules client-side.
index f799452..9b2b676 100644 (file)
@@ -1319,6 +1319,8 @@ unset( $serverName ); # Don't leak local variables to global scope
 
 /**
  * Password reminder name
+ *
+ * @deprecated since 1.23; use the system message 'emailsender' instead.
  */
 $wgPasswordSenderName = 'MediaWiki Mail';
 
index e7c5a32..9832df0 100644 (file)
@@ -3777,8 +3777,9 @@ class User {
         */
        public function sendMail( $subject, $body, $from = null, $replyto = null ) {
                if ( is_null( $from ) ) {
-                       global $wgPasswordSender, $wgPasswordSenderName;
-                       $sender = new MailAddress( $wgPasswordSender, $wgPasswordSenderName );
+                       global $wgPasswordSender;
+                       $sender = new MailAddress( $wgPasswordSender,
+                               wfMessage( 'emailsender' )->inContentLanguage()->text() );
                } else {
                        $sender = new MailAddress( $from );
                }
index 39c3e18..e1d00d3 100644 (file)
@@ -120,6 +120,8 @@ class UserMailer {
        static function arrayToHeaderString( $headers, $endl = "\n" ) {
                $strings = array();
                foreach ( $headers as $name => $value ) {
+                       // Prevent header injection by stripping newlines from value
+                       $value = self::sanitizeHeaderValue( $value );
                        $strings[] = "$name: $value";
                }
                return implode( $endl, $strings );
@@ -393,13 +395,25 @@ class UserMailer {
                self::$mErrorString = preg_replace( '/^mail\(\)(\s*\[.*?\])?: /', '', $string );
        }
 
+       /**
+        * Strips bad characters from a header value to prevent PHP mail header injection attacks
+        * @param string $val String to be santizied
+        * @return string
+        */
+       public static function sanitizeHeaderValue( $val ) {
+               return strtr( $val, array( "\r" => '', "\n" => '' ) );
+       }
+
        /**
         * Converts a string into a valid RFC 822 "phrase", such as is used for the sender name
         * @param $phrase string
         * @return string
         */
        public static function rfc822Phrase( $phrase ) {
-               $phrase = strtr( $phrase, array( "\r" => '', "\n" => '', '"' => '' ) );
+               // Remove line breaks
+               $phrase = self::sanitizeHeaderValue( $phrase );
+               // Remove quotes
+               $phrase = str_replace( '"', '', $phrase );
                return '"' . $phrase . '"';
        }
 
@@ -694,7 +708,7 @@ class EmailNotification {
         * Generate the generic "this page has been changed" e-mail text.
         */
        private function composeCommonMailtext() {
-               global $wgPasswordSender, $wgPasswordSenderName, $wgNoReplyAddress;
+               global $wgPasswordSender, $wgNoReplyAddress;
                global $wgEnotifFromEditor, $wgEnotifRevealEditorAddress;
                global $wgEnotifImpersonal, $wgEnotifUseRealName;
 
@@ -779,7 +793,8 @@ class EmailNotification {
                # Reveal the page editor's address as REPLY-TO address only if
                # the user has not opted-out and the option is enabled at the
                # global configuration level.
-               $adminAddress = new MailAddress( $wgPasswordSender, $wgPasswordSenderName );
+               $adminAddress = new MailAddress( $wgPasswordSender,
+                       wfMessage( 'emailsender' )->inContentLanguage()->text() );
                if ( $wgEnotifRevealEditorAddress
                        && ( $this->editor->getEmail() != '' )
                        && $this->editor->getOption( 'enotifrevealaddr' )
index 908e59c..6695c82 100644 (file)
@@ -330,9 +330,10 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                        // This is a bit ugly, but will serve to differentiate
                        // wiki-borne mails from direct mails and protects against
                        // SPF and bounce problems with some mailers (see below).
-                       global $wgPasswordSender, $wgPasswordSenderName;
+                       global $wgPasswordSender;
 
-                       $mailFrom = new MailAddress( $wgPasswordSender, $wgPasswordSenderName );
+                       $mailFrom = new MailAddress( $wgPasswordSender,
+                               wfMessage( 'emailsender' )->inContentLanguage()->text() );
                        $replyTo = $from;
                } else {
                        // Put the sending user's e-mail address in the From: header.
index f645531..91aa31b 100644 (file)
@@ -1233,6 +1233,7 @@ No email will be sent for any of the following features.',
 Please enter a well-formatted address or empty that field.',
 'cannotchangeemail'               => 'Account email addresses cannot be changed on this wiki.',
 'emaildisabled'                   => 'This site cannot send emails.',
+'emailsender'                     => '{{SITENAME}}', # do not translate or duplicate this message to other languages
 'accountcreated'                  => 'Account created',
 'accountcreatedtext'              => 'The user account for [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) has been created.',
 'createaccount-title'             => 'Account creation for {{SITENAME}}',
index fff02e3..146f0f0 100644 (file)
@@ -1535,6 +1535,7 @@ Appears in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}} afte
 'invalidemailaddress' => 'Shown as a warning when written an invalid email address in [[Special:Preferences]] and {{fullurl:Special:UserLogin|type=signup}} page',
 'cannotchangeemail' => 'Error message shown when user goes to [[Special:ChangeEmail]] but email addresses cannot be changed on the site.',
 'emaildisabled' => 'Error message shown when user tries to set an email address but email features are disabled.',
+'emailsender' => 'From name used in system email sent to users.',
 'accountcreated' => 'Used as page title in [[Special:UserLogin]].
 
 See also:
index 80a31bc..2e6b110 100644 (file)
@@ -131,6 +131,7 @@ $wgIgnoredMessages = array(
        'signupstart',
        'signupend',
        'signupend-https',
+       'emailsender',
        'sitenotice',
        'sitesubtitle',
        'sitetitle',
index 5e463b2..b7c3720 100644 (file)
@@ -550,6 +550,7 @@ $wgMessageStructure = array(
                'invalidemailaddress',
                'cannotchangeemail',
                'emaildisabled',
+               'emailsender',
                'accountcreated',
                'accountcreatedtext',
                'createaccount-title',