@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.

Use better secrets in generating account tokens

Summary:
When we generate account tokens for CSRF keys and email verification, one of the inputs we use is the user's password hash. Users won't always have a password hash, so this is a weak input to key generation. This also couples CSRF weirdly with auth concerns.

Instead, give users a dedicated secret for use in token generation which is used only for this purpose.

Test Plan:
- Ran upgrade scripts.
- Verified all users got new secrets.
- Created a new user.
- Verified they got a secret.
- Submitted CSRF'd forms, they worked.
- Adjusted the CSRF token and submitted CSRF'd forms, verified they don't work.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

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

+33 -1
+2
resources/sql/autopatches/20140410.accountsecret.1.sql
··· 1 + ALTER TABLE {$NAMESPACE}_user.user 2 + ADD accountSecret CHAR(64) NOT NULL COLLATE latin1_bin;
+23
resources/sql/autopatches/20140410.accountsecret.2.php
··· 1 + <?php 2 + 3 + echo "Updating users...\n"; 4 + 5 + 6 + foreach (new LiskMigrationIterator(new PhabricatorUser()) as $user) { 7 + 8 + $id = $user->getID(); 9 + echo "Updating {$id}...\n"; 10 + 11 + if (strlen($user->getAccountSecret())) { 12 + continue; 13 + } 14 + 15 + queryfx( 16 + $user->establishConnection('w'), 17 + 'UPDATE %T SET accountSecret = %s WHERE id = %d', 18 + $user->getTableName(), 19 + Filesystem::readRandomCharacters(64), 20 + $id); 21 + } 22 + 23 + echo "Done.\n";
+8 -1
src/applications/people/storage/PhabricatorUser.php
··· 32 32 protected $isEmailVerified = 0; 33 33 protected $isApproved = 0; 34 34 35 + protected $accountSecret; 36 + 35 37 private $profileImage = self::ATTACHABLE; 36 38 private $profile = null; 37 39 private $status = self::ATTACHABLE; ··· 157 159 if (!$this->getConduitCertificate()) { 158 160 $this->setConduitCertificate($this->generateConduitCertificate()); 159 161 } 162 + 163 + if (!strlen($this->getAccountSecret())) { 164 + $this->setAccountSecret(Filesystem::readRandomCharacters(64)); 165 + } 166 + 160 167 $result = parent::save(); 161 168 162 169 if ($this->profile) { ··· 305 312 306 313 private function generateToken($epoch, $frequency, $key, $len) { 307 314 if ($this->getPHID()) { 308 - $vec = $this->getPHID().$this->getPasswordHash(); 315 + $vec = $this->getPHID().$this->getAccountSecret(); 309 316 } else { 310 317 $vec = $this->getAlternateCSRFString(); 311 318 }