Changeset View
Changeset View
Standalone View
Standalone View
src/applications/auth/engine/PhabricatorAuthSessionEngine.php
Show First 20 Lines • Show All 241 Lines • ▼ Show 20 Lines | public function requireHighSecuritySession( | ||||
// without putting the session into high security mode. This is generally | // without putting the session into high security mode. This is generally | ||||
// easier for users. A minor but desirable side effect is that when a user | // easier for users. A minor but desirable side effect is that when a user | ||||
// adds an auth factor, existing sessions won't get a free pass into hisec, | // adds an auth factor, existing sessions won't get a free pass into hisec, | ||||
// since they never actually got marked as hisec. | // since they never actually got marked as hisec. | ||||
if (!$factors) { | if (!$factors) { | ||||
return $this->issueHighSecurityToken($session, true); | return $this->issueHighSecurityToken($session, true); | ||||
} | } | ||||
// Check for a rate limit without awarding points, so the user doesn't | |||||
// get partway through the workflow only to get blocked. | |||||
PhabricatorSystemActionEngine::willTakeAction( | |||||
array($viewer->getPHID()), | |||||
new PhabricatorAuthTryFactorAction(), | |||||
0); | |||||
$validation_results = array(); | $validation_results = array(); | ||||
if ($request->isHTTPPost()) { | if ($request->isHTTPPost()) { | ||||
$request->validateCSRF(); | $request->validateCSRF(); | ||||
if ($request->getExists(AphrontRequest::TYPE_HISEC)) { | if ($request->getExists(AphrontRequest::TYPE_HISEC)) { | ||||
// Limit factor verification rates to prevent brute force attacks. | |||||
PhabricatorSystemActionEngine::willTakeAction( | |||||
array($viewer->getPHID()), | |||||
new PhabricatorAuthTryFactorAction(), | |||||
1); | |||||
$ok = true; | $ok = true; | ||||
foreach ($factors as $factor) { | foreach ($factors as $factor) { | ||||
$id = $factor->getID(); | $id = $factor->getID(); | ||||
$impl = $factor->requireImplementation(); | $impl = $factor->requireImplementation(); | ||||
$validation_results[$id] = $impl->processValidateFactorForm( | $validation_results[$id] = $impl->processValidateFactorForm( | ||||
$factor, | $factor, | ||||
$viewer, | $viewer, | ||||
$request); | $request); | ||||
if (!$impl->isFactorValid($factor, $validation_results[$id])) { | if (!$impl->isFactorValid($factor, $validation_results[$id])) { | ||||
$ok = false; | $ok = false; | ||||
} | } | ||||
} | } | ||||
if ($ok) { | if ($ok) { | ||||
// Give the user a credit back for a successful factor verification. | |||||
PhabricatorSystemActionEngine::willTakeAction( | |||||
array($viewer->getPHID()), | |||||
new PhabricatorAuthTryFactorAction(), | |||||
-1); | |||||
$until = time() + phutil_units('15 minutes in seconds'); | $until = time() + phutil_units('15 minutes in seconds'); | ||||
$session->setHighSecurityUntil($until); | $session->setHighSecurityUntil($until); | ||||
queryfx( | queryfx( | ||||
$session->establishConnection('w'), | $session->establishConnection('w'), | ||||
'UPDATE %T SET highSecurityUntil = %d WHERE id = %d', | 'UPDATE %T SET highSecurityUntil = %d WHERE id = %d', | ||||
$session->getTableName(), | $session->getTableName(), | ||||
$until, | $until, | ||||
$session->getID()); | $session->getID()); | ||||
$log = PhabricatorUserLog::initializeNewLog( | $log = PhabricatorUserLog::initializeNewLog( | ||||
$viewer, | $viewer, | ||||
$viewer->getPHID(), | $viewer->getPHID(), | ||||
PhabricatorUserLog::ACTION_ENTER_HISEC); | PhabricatorUserLog::ACTION_ENTER_HISEC); | ||||
$log->save(); | $log->save(); | ||||
} else { | } else { | ||||
$log = PhabricatorUserLog::initializeNewLog( | $log = PhabricatorUserLog::initializeNewLog( | ||||
$viewer, | $viewer, | ||||
$viewer->getPHID(), | $viewer->getPHID(), | ||||
PhabricatorUserLog::ACTION_FAIL_HISEC); | PhabricatorUserLog::ACTION_FAIL_HISEC); | ||||
$log->save(); | $log->save(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 77 Lines • Show Last 20 Lines |