Harden sign-in and password reset
- OTP attempt limits, constant-time compare, random reference codes - DB-backed rate limits (429) on sign-in, OTP, reset, register, onboarding - one generic sign-in failure message; reset request no longer reveals accounts - no password kept in the session; real status codes on failures
This commit is contained in:
@@ -55,6 +55,8 @@ require_once '../../../config.php';
|
||||
require_once '../../../dbconn.php';
|
||||
require_once '../../../assets/utils/db_helpers.php';
|
||||
require_once '../../../assets/utils/otp_policy.php';
|
||||
require_once '../../../assets/utils/rate_limit.php';
|
||||
require_once '../../../assets/utils/secret_box.php';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
@@ -85,7 +87,7 @@ if ($sth->fetchColumn() !== 'owner') {
|
||||
// ── Step 2: CSRF check ────────────────────────────────────────────────────────
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$csrf = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
|
||||
if (empty($csrf) || $csrf !== ($_SESSION['csrf_token'] ?? '')) {
|
||||
if (empty($csrf) || !hash_equals((string)($_SESSION['csrf_token'] ?? ''), $csrf)) {
|
||||
http_response_code(403);
|
||||
$answer['message'] = 'Invalid request.';
|
||||
exit(json_encode($answer));
|
||||
@@ -94,6 +96,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
$data = json_decode($_POST['json'] ?? '{}', true) ?: [];
|
||||
|
||||
// ── Step 2b: Throttle — each attempt sends an SMTP test email ────────────────
|
||||
rate_limit_guard($pdo1, [
|
||||
['onboarding_ip', rate_limit_client_ip(), 20, 900],
|
||||
['onboarding_user', (string)$user_id, 10, 900],
|
||||
]);
|
||||
|
||||
try {
|
||||
|
||||
// ── Step 3: Sanitise input ────────────────────────────────────────────────
|
||||
@@ -147,7 +155,7 @@ try {
|
||||
// ── Step 7: Encrypt SMTP password ────────────────────────────────────
|
||||
// Uses the same OpenSSL method/iv/key as the rest of the app (from config.php)
|
||||
// so the stored password can be decrypted by the mailer module.
|
||||
$encrypted_pass = openssl_encrypt($smtp_password, $method, $pinkey, 0, $iv);
|
||||
$encrypted_pass = secret_encrypt($smtp_password, $pinkey);
|
||||
|
||||
// Assemble a temporary SMTP config for the test send (step 8)
|
||||
$smtp_config = [
|
||||
|
||||
Reference in New Issue
Block a user