@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

Repository Identity "Automatically Detected User": don't trust unverified emails

Summary:
Make sure that Repository Diffusion Identities "Automatically Detected User " are not created from unverified emails.

Closes T15965

Test Plan:
Find at least one identity that is assigned to nobody:

http://phorge.localhost/diffusion/identity/

(For example, you may easily find an identity of "GitHub <noreply@github.com>")

(Double check that its "Assigned To" is unset or make sure it's unset for this test)

Be evil: add *that* email in your {nav Profile > Settings > Email addresses}. So, for example add "noreply@github.com", like a rogue. The email can stay unverified.

Run this command to immediately cause an effect:

./bin/repository rebuild-identities --all-identities

- before this change, you can reproduce that you successfully steal that identity and you become "GitHub" or whoever
- after this change, you see that "Automatically Detected User" is unset again
- after this change, any other identity manually assigned, is still assigned to that value
- after this change, any other identity automatically assigned to verified emails, are still "Automatically Detected User"

Reviewers: O1 Blessed Committers, speck, 20after4

Reviewed By: O1 Blessed Committers, speck, 20after4

Subscribers: aklapper, tobiaswiese, Matthew, Cigaryno

Maniphest Tasks: T15965

Differential Revision: https://we.phorge.it/D25845

+25 -2
+2 -1
src/applications/diffusion/query/DiffusionResolveUserQuery.php
··· 93 93 94 94 95 95 private function findUserByEmailAddress($email_address) { 96 - $by_email = PhabricatorUser::loadOneWithEmailAddress($email_address); 96 + $by_email = 97 + PhabricatorUser::loadOneWithVerifiedEmailAddress($email_address); 97 98 98 99 if ($by_email) { 99 100 return $by_email->getPHID();
+22
src/applications/people/storage/PhabricatorUser.php
··· 652 652 return $this->getUsername(); 653 653 } 654 654 655 + /** 656 + * Load one user from their verified email address. 657 + * @param string $address 658 + * @return PhabricatorUser|null 659 + */ 660 + public static function loadOneWithVerifiedEmailAddress($address) { 661 + $email = id(new PhabricatorUserEmail())->loadOneWhere( 662 + 'address = %s AND isVerified = 1', 663 + $address); 664 + if (!$email) { 665 + return null; 666 + } 667 + return id(new self())->loadOneWhere( 668 + 'phid = %s', 669 + $email->getUserPHID()); 670 + } 671 + 672 + /** 673 + * Load one user from their potentially unverified email address. 674 + * @param string $address 675 + * @return PhabricatorUser|null 676 + */ 655 677 public static function loadOneWithEmailAddress($address) { 656 678 $email = id(new PhabricatorUserEmail())->loadOneWhere( 657 679 'address = %s',
+1 -1
src/applications/repository/management/PhabricatorRepositoryManagementRebuildIdentitiesWorkflow.php
··· 281 281 $user->getMonogram())); 282 282 283 283 $emails = id(new PhabricatorUserEmail())->loadAllWhere( 284 - 'userPHID = %s', 284 + 'userPHID = %s AND isVerified = 1', 285 285 $user->getPHID()); 286 286 if ($emails) { 287 287 $this->rebuildEmails(mpull($emails, 'getAddress'));