Cleanup login/reset functionality, address security issue with 2FA pathways
This commit is contained in:
parent
eade81f89b
commit
c3e462ab2f
11 changed files with 158 additions and 39 deletions
|
@ -106,6 +106,10 @@ abstract class AbstractLoginController extends Controller
|
|||
$this->getField($request->input('user')) => $request->input('user'),
|
||||
]);
|
||||
|
||||
if ($request->route()->named('auth.checkpoint')) {
|
||||
throw new DisplayException(trans('auth.checkpoint_failed'));
|
||||
}
|
||||
|
||||
throw new DisplayException(trans('auth.failed'));
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace Pterodactyl\Http\Controllers\Auth;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Events\Auth\FailedPasswordReset;
|
||||
|
@ -18,9 +18,9 @@ class ForgotPasswordController extends Controller
|
|||
*
|
||||
* @param \Illuminate\Http\Request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, $response): RedirectResponse
|
||||
protected function sendResetLinkFailedResponse(Request $request, $response): JsonResponse
|
||||
{
|
||||
// As noted in #358 we will return success even if it failed
|
||||
// to avoid pointing out that an account does or does not
|
||||
|
@ -34,9 +34,9 @@ class ForgotPasswordController extends Controller
|
|||
* Get the response for a successful password reset link.
|
||||
*
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetLinkResponse($response)
|
||||
protected function sendResetLinkResponse($response): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'status' => trans($response),
|
||||
|
|
|
@ -10,9 +10,8 @@ class LoginCheckpointController extends AbstractLoginController
|
|||
{
|
||||
/**
|
||||
* Handle a login where the user is required to provide a TOTP authentication
|
||||
* token. In order to add additional layers of security, users are not
|
||||
* informed of an incorrect password until this stage, forcing them to
|
||||
* provide a token on each login attempt.
|
||||
* token. Once a user has reached this stage it is assumed that they have already
|
||||
* provided a valid username and password.
|
||||
*
|
||||
* @param \Pterodactyl\Http\Requests\Auth\LoginCheckpointRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
|
@ -28,7 +27,7 @@ class LoginCheckpointController extends AbstractLoginController
|
|||
return $this->sendFailedLoginResponse($request);
|
||||
}
|
||||
|
||||
if (! array_get($cache, 'valid_credentials') || array_get($cache, 'request_ip') !== $request->ip()) {
|
||||
if (array_get($cache, 'request_ip') !== $request->ip()) {
|
||||
return $this->sendFailedLoginResponse($request, $user);
|
||||
}
|
||||
|
||||
|
@ -40,7 +39,7 @@ class LoginCheckpointController extends AbstractLoginController
|
|||
return $this->sendFailedLoginResponse($request, $user);
|
||||
}
|
||||
|
||||
$this->authManager->guard()->login($user, true);
|
||||
$this->auth->guard()->login($user, true);
|
||||
|
||||
return $this->sendLoginResponse($request);
|
||||
}
|
||||
|
|
|
@ -33,22 +33,26 @@ class LoginController extends AbstractLoginController
|
|||
return $this->sendFailedLoginResponse($request);
|
||||
}
|
||||
|
||||
$validCredentials = password_verify($request->input('password'), $user->password);
|
||||
// Ensure that the account is using a valid username and password before trying to
|
||||
// continue. Previously this was handled in the 2FA checkpoint, however that has
|
||||
// a flaw in which you can discover if an account exists simply by seeing if you
|
||||
// can proceede to the next step in the login process.
|
||||
if (! password_verify($request->input('password'), $user->password)) {
|
||||
return $this->sendFailedLoginResponse($request, $user);
|
||||
}
|
||||
|
||||
// If the user is using 2FA we do not actually log them in at this step, we return
|
||||
// a one-time token to link the 2FA credentials to this account via the UI.
|
||||
if ($user->use_totp) {
|
||||
$token = str_random(128);
|
||||
$this->cache->put($token, [
|
||||
'user_id' => $user->id,
|
||||
'valid_credentials' => $validCredentials,
|
||||
'request_ip' => $request->ip(),
|
||||
], 5);
|
||||
|
||||
return response()->json(['complete' => false, 'token' => $token]);
|
||||
}
|
||||
|
||||
if (! $validCredentials) {
|
||||
return $this->sendFailedLoginResponse($request, $user);
|
||||
}
|
||||
|
||||
$this->auth->guard()->login($user, true);
|
||||
|
||||
return response()->json(['complete' => true]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue