From 1768f90bc83943288e85f086ea7e56a435520fc1 Mon Sep 17 00:00:00 2001 From: theopolisme Date: Tue, 31 Dec 2013 00:12:09 -0600 Subject: [PATCH] Deprecate $wgPasswordSenderName 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 | 2 ++ includes/DefaultSettings.php | 2 ++ includes/User.php | 5 +++-- includes/UserMailer.php | 21 ++++++++++++++++++--- includes/specials/SpecialEmailuser.php | 5 +++-- languages/messages/MessagesEn.php | 1 + languages/messages/MessagesQqq.php | 1 + maintenance/language/messageTypes.inc | 1 + maintenance/language/messages.inc | 1 + 9 files changed, 32 insertions(+), 7 deletions(-) diff --git a/RELEASE-NOTES-1.23 b/RELEASE-NOTES-1.23 index a7ae1616d4..216ab6780f 100644 --- a/RELEASE-NOTES-1.23 +++ b/RELEASE-NOTES-1.23 @@ -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. diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index f799452653..9b2b6762f4 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -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'; diff --git a/includes/User.php b/includes/User.php index e7c5a326f4..9832df0e3b 100644 --- a/includes/User.php +++ b/includes/User.php @@ -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 ); } diff --git a/includes/UserMailer.php b/includes/UserMailer.php index 39c3e18db6..e1d00d33f8 100644 --- a/includes/UserMailer.php +++ b/includes/UserMailer.php @@ -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' ) diff --git a/includes/specials/SpecialEmailuser.php b/includes/specials/SpecialEmailuser.php index 908e59c36f..6695c82209 100644 --- a/includes/specials/SpecialEmailuser.php +++ b/includes/specials/SpecialEmailuser.php @@ -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. diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index f645531633..91aa31bf0e 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -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}}', diff --git a/languages/messages/MessagesQqq.php b/languages/messages/MessagesQqq.php index fff02e3b61..146f0f03ef 100644 --- a/languages/messages/MessagesQqq.php +++ b/languages/messages/MessagesQqq.php @@ -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: diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc index 80a31bc707..2e6b110873 100644 --- a/maintenance/language/messageTypes.inc +++ b/maintenance/language/messageTypes.inc @@ -131,6 +131,7 @@ $wgIgnoredMessages = array( 'signupstart', 'signupend', 'signupend-https', + 'emailsender', 'sitenotice', 'sitesubtitle', 'sitetitle', diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index 5e463b2404..b7c3720039 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -550,6 +550,7 @@ $wgMessageStructure = array( 'invalidemailaddress', 'cannotchangeemail', 'emaildisabled', + 'emailsender', 'accountcreated', 'accountcreatedtext', 'createaccount-title', -- 2.20.1