Page MenuHomePhabricator

D19953.id47629.diff
No OneTemporary

D19953.id47629.diff

diff --git a/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php b/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php
--- a/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php
+++ b/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php
@@ -191,10 +191,7 @@
$this->newOption('cluster.mailers', 'cluster.mailers', null)
->setHidden(true)
->setDescription($mailers_description),
- $this->newOption(
- 'metamta.default-address',
- 'string',
- 'noreply@phabricator.example.com')
+ $this->newOption('metamta.default-address', 'string', null)
->setDescription(pht('Default "From" address.')),
$this->newOption(
'metamta.one-mail-per-recipient',
diff --git a/src/applications/metamta/editor/PhabricatorMetaMTAApplicationEmailEditor.php b/src/applications/metamta/editor/PhabricatorMetaMTAApplicationEmailEditor.php
--- a/src/applications/metamta/editor/PhabricatorMetaMTAApplicationEmailEditor.php
+++ b/src/applications/metamta/editor/PhabricatorMetaMTAApplicationEmailEditor.php
@@ -104,6 +104,16 @@
pht('Invalid'),
pht('Email address is not formatted properly.'));
}
+
+ $address = new PhutilEmailAddress($email);
+ if (PhabricatorMailUtil::isReservedAddress($address)) {
+ $errors[] = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Reserved'),
+ pht(
+ 'This email address is reserved. Choose a different '.
+ 'address.'));
+ }
}
$missing = $this->validateIsEmptyTextField(
diff --git a/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php b/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php
--- a/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php
+++ b/src/applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php
@@ -41,4 +41,30 @@
}
}
+ public function testReservedAddresses() {
+ $default_address = id(new PhabricatorMetaMTAMail())
+ ->newDefaultEmailAddress();
+
+ $void_address = id(new PhabricatorMetaMTAMail())
+ ->newVoidEmailAddress();
+
+ $map = array(
+ 'alincoln@example.com' => false,
+ 'sysadmin@example.com' => true,
+ 'hostmaster@example.com' => true,
+ '"Walter Ebmaster" <webmaster@example.com>' => true,
+ (string)$default_address => true,
+ (string)$void_address => true,
+ );
+
+ foreach ($map as $raw_address => $expect) {
+ $address = new PhutilEmailAddress($raw_address);
+
+ $this->assertEqual(
+ $expect,
+ PhabricatorMailUtil::isReservedAddress($address),
+ pht('Reserved: %s', $raw_address));
+ }
+ }
+
}
diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
--- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
+++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
@@ -713,7 +713,7 @@
$actors = $this->loadAllActors();
$deliverable_actors = $this->filterDeliverableActors($actors);
- $default_from = PhabricatorEnv::getEnvConfig('metamta.default-address');
+ $default_from = (string)$this->newDefaultEmailAddress();
if (empty($params['from'])) {
$mailer->setFrom($default_from);
}
@@ -1463,18 +1463,33 @@
}
private function newMailDomain() {
+ $domain = PhabricatorEnv::getEnvConfig('metamta.reply-handler-domain');
+ if (strlen($domain)) {
+ return $domain;
+ }
+
$install_uri = PhabricatorEnv::getURI('/');
$install_uri = new PhutilURI($install_uri);
return $install_uri->getDomain();
}
- public function newVoidEmailAddress() {
+ public function newDefaultEmailAddress() {
+ $raw_address = PhabricatorEnv::getEnvConfig('metamta.default-address');
+ if (strlen($raw_address)) {
+ return new PhutilEmailAddress($raw_address);
+ }
+
$domain = $this->newMailDomain();
- $address = "void-recipient@{$domain}";
+ $address = "noreply@{$domain}";
+
return new PhutilEmailAddress($address);
}
+ public function newVoidEmailAddress() {
+ return $this->newDefaultEmailAddress();
+ }
+
/* -( Routing )------------------------------------------------------------ */
diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php
--- a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php
+++ b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php
@@ -161,10 +161,19 @@
->setFilterMethod('isEnabled')
->execute();
+ $targets = $this->newTargetAddresses();
+ foreach ($targets as $key => $target) {
+ // Never accept any reserved address as a mail target. This prevents
+ // security issues around "hostmaster@" and bad behavior with
+ // "noreply@".
+ if (PhabricatorMailUtil::isReservedAddress($target)) {
+ unset($targets[$key]);
+ continue;
+ }
+ }
+
$any_accepted = false;
$receiver_exception = null;
-
- $targets = $this->newTargetAddresses();
foreach ($receivers as $receiver) {
$receiver = id(clone $receiver)
->setViewer($viewer);
diff --git a/src/applications/metamta/util/PhabricatorMailUtil.php b/src/applications/metamta/util/PhabricatorMailUtil.php
--- a/src/applications/metamta/util/PhabricatorMailUtil.php
+++ b/src/applications/metamta/util/PhabricatorMailUtil.php
@@ -62,4 +62,50 @@
return ($u->getAddress() === $v->getAddress());
}
+ public static function isReservedAddress(PhutilEmailAddress $address) {
+ $address = self::normalizeAddress($address);
+ $local = $address->getLocalPart();
+
+ $reserved = array(
+ 'admin',
+ 'administrator',
+ 'hostmaster',
+ 'list',
+ 'list-request',
+ 'majordomo',
+ 'postmaster',
+ 'root',
+ 'ssl-admin',
+ 'ssladmin',
+ 'ssladministrator',
+ 'sslwebmaster',
+ 'sysadmin',
+ 'uucp',
+ 'webmaster',
+
+ 'noreply',
+ 'no-reply',
+ );
+
+ $reserved = array_fuse($reserved);
+
+ if (isset($reserved[$local])) {
+ return true;
+ }
+
+ $default_address = id(new PhabricatorMetaMTAMail())
+ ->newDefaultEmailAddress();
+ if (self::matchAddresses($address, $default_address)) {
+ return true;
+ }
+
+ $void_address = id(new PhabricatorMetaMTAMail())
+ ->newVoidEmailAddress();
+ if (self::matchAddresses($address, $void_address)) {
+ return true;
+ }
+
+ return false;
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 3:30 PM (19 h, 58 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6786242
Default Alt Text
D19953.id47629.diff (6 KB)

Event Timeline