Page MenuHomePhabricator

D18906.id45367.diff
No OneTemporary

D18906.id45367.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2033,6 +2033,7 @@
'PhabricatorAuthApplication' => 'applications/auth/application/PhabricatorAuthApplication.php',
'PhabricatorAuthAuthFactorPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php',
'PhabricatorAuthAuthProviderPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php',
+ 'PhabricatorAuthChangePasswordAction' => 'applications/auth/action/PhabricatorAuthChangePasswordAction.php',
'PhabricatorAuthConduitAPIMethod' => 'applications/auth/conduit/PhabricatorAuthConduitAPIMethod.php',
'PhabricatorAuthConduitTokenRevoker' => 'applications/auth/revoker/PhabricatorAuthConduitTokenRevoker.php',
'PhabricatorAuthConfirmLinkController' => 'applications/auth/controller/PhabricatorAuthConfirmLinkController.php',
@@ -7321,6 +7322,7 @@
'PhabricatorAuthApplication' => 'PhabricatorApplication',
'PhabricatorAuthAuthFactorPHIDType' => 'PhabricatorPHIDType',
'PhabricatorAuthAuthProviderPHIDType' => 'PhabricatorPHIDType',
+ 'PhabricatorAuthChangePasswordAction' => 'PhabricatorSystemAction',
'PhabricatorAuthConduitAPIMethod' => 'ConduitAPIMethod',
'PhabricatorAuthConduitTokenRevoker' => 'PhabricatorAuthRevoker',
'PhabricatorAuthConfirmLinkController' => 'PhabricatorAuthController',
diff --git a/src/applications/auth/action/PhabricatorAuthChangePasswordAction.php b/src/applications/auth/action/PhabricatorAuthChangePasswordAction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/action/PhabricatorAuthChangePasswordAction.php
@@ -0,0 +1,22 @@
+<?php
+
+final class PhabricatorAuthChangePasswordAction
+ extends PhabricatorSystemAction {
+
+ const TYPECONST = 'auth.password';
+
+ public function getActionConstant() {
+ return self::TYPECONST;
+ }
+
+ public function getScoreThreshold() {
+ return 20 / phutil_units('1 hour in seconds');
+ }
+
+ public function getLimitExplanation() {
+ return pht(
+ 'You have failed to enter the correct account password too often in '.
+ 'a short period of time.');
+ }
+
+}
diff --git a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php
--- a/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorPasswordSettingsPanel.php
@@ -25,11 +25,13 @@
}
public function processRequest(AphrontRequest $request) {
- $user = $request->getUser();
+ $viewer = $request->getUser();
+ $user = $this->getUser();
+
$content_source = PhabricatorContentSource::newFromRequest($request);
$token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
- $user,
+ $viewer,
$request,
'/settings/');
@@ -44,7 +46,7 @@
$account_type = PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT;
$password_objects = id(new PhabricatorAuthPasswordQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withObjectPHIDs(array($user->getPHID()))
->withPasswordTypes(array($account_type))
->withIsRevoked(false)
@@ -63,10 +65,18 @@
$errors = array();
if ($request->isFormPost()) {
+ // Rate limit guesses about the old password. This page requires MFA and
+ // session compromise already, so this is mostly just to stop researchers
+ // from reporting this as a vulnerability.
+ PhabricatorSystemActionEngine::willTakeAction(
+ array($viewer->getPHID()),
+ new PhabricatorAuthChangePasswordAction(),
+ 1);
+
$envelope = new PhutilOpaqueEnvelope($request->getStr('old_pw'));
$engine = id(new PhabricatorAuthPasswordEngine())
- ->setViewer($user)
+ ->setViewer($viewer)
->setContentSource($content_source)
->setPasswordType($account_type)
->setObject($user);
@@ -79,6 +89,12 @@
$e_old = pht('Invalid');
} else {
$e_old = null;
+
+ // Refund the user an action credit for getting the password right.
+ PhabricatorSystemActionEngine::willTakeAction(
+ array($viewer->getPHID()),
+ new PhabricatorAuthChangePasswordAction(),
+ -1);
}
$pass = $request->getStr('new_pw');
@@ -142,7 +158,7 @@
}
$form = id(new AphrontFormView())
- ->setViewer($user)
+ ->setViewer($viewer)
->appendChild(
id(new AphrontFormPasswordControl())
->setLabel(pht('Old Password'))

File Metadata

Mime Type
text/plain
Expires
Thu, May 9, 9:26 PM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6277950
Default Alt Text
D18906.id45367.diff (4 KB)

Event Timeline