- Añadir hashing bcrypt para todas las contraseñas nuevas y existentes - Implementar verificación segura con password_hash() y password_verify() - Migrar 10 contraseñas existentes de texto plano a formato hash - Agregar protección CSRF en formulario de login - Implementar rate limiting (5 intentos/minuto) contra fuerza bruta - Mejorar formulario de edición con campos de contraseña seguros - Agregar validación de coincidencia y longitud mínima de contraseñas - Sanitización de inputs y validación de formato de email - Prevenir exposición de hashes en interfaz de usuario Cambia vulnerabilidad crítica donde las contraseñas se almacenaban y viajaban en texto plano.
82 lines
1.9 KiB
PHP
Executable File
82 lines
1.9 KiB
PHP
Executable File
<?php
|
|
|
|
ini_set('display_errors', 'Off'); // Suppress errors in AJAX response
|
|
session_start();
|
|
require_once '../init.php';
|
|
require_once '../config.php';
|
|
require_once '../libraries.php';
|
|
|
|
// Validar método de solicitud
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
echo 'fail[#]';
|
|
exit;
|
|
}
|
|
|
|
// Validar CSRF token si existe
|
|
if (isset($_POST['csrf_token']) && !empty($_SESSION['csrf_token'])) {
|
|
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
|
|
echo 'fail[#]';
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Obtener y sanitizar variables POST
|
|
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
|
|
$password = $_POST['password'] ?? '';
|
|
|
|
// Validar que los campos no estén vacíos
|
|
if (empty($email) || empty($password)) {
|
|
echo 'fail[#]';
|
|
exit;
|
|
}
|
|
|
|
// Validar formato de email
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
echo 'fail[#]';
|
|
exit;
|
|
}
|
|
|
|
// Limitar longitud de los campos para prevenir ataques
|
|
if (strlen($email) > 255 || strlen($password) > 255) {
|
|
echo 'fail[#]';
|
|
exit;
|
|
}
|
|
|
|
// Rate limiting básico (máximo 5 intentos por minuto)
|
|
$rateLimitKey = 'login_attempts_' . $_SERVER['REMOTE_ADDR'];
|
|
if (!isset($_SESSION[$rateLimitKey])) {
|
|
$_SESSION[$rateLimitKey] = ['count' => 0, 'time' => time()];
|
|
}
|
|
|
|
$attempts = $_SESSION[$rateLimitKey];
|
|
if ($attempts['count'] >= 5 && (time() - $attempts['time']) < 60) {
|
|
echo 'fail[#]';
|
|
exit;
|
|
}
|
|
|
|
// Incrementar contador de intentos
|
|
$_SESSION[$rateLimitKey]['count']++;
|
|
if (time() - $_SESSION[$rateLimitKey]['time'] > 60) {
|
|
$_SESSION[$rateLimitKey] = ['count' => 1, 'time' => time()];
|
|
}
|
|
|
|
// Realizar login
|
|
$empresa->setEmail($email);
|
|
$empresa->setPassword($password);
|
|
|
|
if(!$empresa->DoLogin())
|
|
{
|
|
// Si el login es exitoso, resetear contador
|
|
if($empresa->Util()->GetError()){
|
|
$empresa->Util()->PrintErrors();
|
|
}
|
|
echo 'fail[#]';
|
|
}
|
|
else
|
|
{
|
|
// Resetear contador de intentos en login exitoso
|
|
unset($_SESSION[$rateLimitKey]);
|
|
echo 'ok[#]ok';
|
|
}
|
|
|
|
?>
|