@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Don't count "Cc: x@y.com" as a legitimate recipient if the user who has "x@y.com" attached to their account has not verified the address

Summary:
Fixes T13317. On `admin.phacility.com`, an enterprising user added `noreply@admin.phacility.com` to their account. This caused them to become CC'd on several support issues over the last year, because we send mail "From" this address and it can get CC'd via reply/reply all/whatever else.

The original driving goal here is that if I reply to a task email and CC you on my reply, that should count as a CC in Phabricator, since this aligns with user intent and keeps them in the loop.

This misfire on `noreply@` is ultimately harmless (being CC'd does not grant the user access permission, see T4411), but confusing and undesirable. Instead:

- Don't allow reserved addresses ("noreply@", "ssladmin@", etc) to trigger this subscribe-via-CC behavior.
- Only count verified addresses as legitimate user recipients.

Test Plan:
- Added a `bin/mail receive-test --cc ...` flag to make this easier to test.
- Sent mail as `bin/mail receive-test --to X --as alice --cc bailey@verified.com`. Bailey was CC'd both before and after the change.
- Sent mail as `bin/mail receive-test --to X --as alice --cc unverified@imaginary.com`, an address which Bailey has added to her account but not verified.
- Before change: Bailey was CC'd on the task anyway.
- After change: Bailey is not CC'd on the task.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13317

Differential Revision: https://secure.phabricator.com/D20593

+42 -14
+9
src/applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php
··· 29 29 'param' => 'object', 30 30 'help' => pht('Simulate mail delivery "To:" the given object.'), 31 31 ), 32 + array( 33 + 'name' => 'cc', 34 + 'param' => 'address', 35 + 'help' => pht('Simulate a mail delivery "Cc:" address.'), 36 + 'repeat' => true, 37 + ), 32 38 )); 33 39 } 34 40 ··· 84 90 $from = $user->loadPrimaryEmail()->getAddress(); 85 91 } 86 92 93 + $cc = $args->getArg('cc'); 94 + 87 95 $console->writeErr("%s\n", pht('Reading message body from stdin...')); 88 96 $body = file_get_contents('php://stdin'); 89 97 ··· 91 99 $header_content = array( 92 100 'Message-ID' => Filesystem::readRandomCharacters(12), 93 101 'From' => $from, 102 + 'Cc' => implode(', ', $cc), 94 103 ); 95 104 96 105 if (preg_match('/.+@.+/', $to)) {
+33 -14
src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php
··· 104 104 } 105 105 106 106 public function loadAllRecipientPHIDs() { 107 - $addresses = array_merge( 108 - $this->getToAddresses(), 109 - $this->getCCAddresses()); 107 + $addresses = $this->newTargetAddresses(); 110 108 111 - return $this->loadPHIDsFromAddresses($addresses); 112 - } 109 + // See T13317. Don't allow reserved addresses (like "noreply@...") to 110 + // match user PHIDs. 111 + foreach ($addresses as $key => $address) { 112 + if (PhabricatorMailUtil::isReservedAddress($address)) { 113 + unset($addresses[$key]); 114 + } 115 + } 113 116 114 - public function loadCCPHIDs() { 115 - return $this->loadPHIDsFromAddresses($this->getCCAddresses()); 116 - } 117 + if (!$addresses) { 118 + return array(); 119 + } 117 120 118 - private function loadPHIDsFromAddresses(array $addresses) { 119 - if (empty($addresses)) { 120 - return array(); 121 + $address_strings = array(); 122 + foreach ($addresses as $address) { 123 + $address_strings[] = phutil_string_cast($address->getAddress()); 121 124 } 122 - $users = id(new PhabricatorUserEmail()) 123 - ->loadAllWhere('address IN (%Ls)', $addresses); 124 - return mpull($users, 'getUserPHID'); 125 + 126 + // See T13317. If a verified email address is in the "To" or "Cc" line, 127 + // we'll count the user who owns that address as a recipient. 128 + 129 + // We require the address be verified because we'll trigger behavior (like 130 + // adding subscribers) based on the recipient list, and don't want to add 131 + // Alice as a subscriber if she adds an unverified "internal-bounces@" 132 + // address to her account and this address gets caught in the crossfire. 133 + // In the best case this is confusing; in the worst case it could 134 + // some day give her access to objects she can't see. 135 + 136 + $recipients = id(new PhabricatorUserEmail()) 137 + ->loadAllWhere( 138 + 'address IN (%Ls) AND isVerified = 1', 139 + $address_strings); 140 + 141 + $recipient_phids = mpull($recipients, 'getUserPHID'); 142 + 143 + return $recipient_phids; 125 144 } 126 145 127 146 public function processReceivedMail() {