Seguridad de inicio de sesión en el sitio web (¿Es suficientemente seguro?)

4

Estoy creando un sitio más grande por primera vez, por lo que la seguridad realmente importa, a diferencia de mis tableros realmente malos, con quizás 10 usuarios. Así que quería preguntarme si la forma en que lo hago es lo suficientemente segura para una aplicación semi-grande donde hay dinero involucrado.

El sitio está escrito en PHP, la base de datos es MySql. Este es el inicio de sesión actual.

En primer lugar, tengo una clave de sesión y sal de 128 signos guardados en la configuración local.
En cada sitio que interactúa con las sesiones (por ejemplo, el panel de control del usuario) tengo este fragmento de código al comienzo del código:

session_start();
if (empty($_SESSION)) {
    session_regenerate_id(true);
}

Después de eso, me conecto a la base de datos, escapa todas las cadenas y leo los datos.
Después de eso, comparo las dos contraseñas que se procesaron con SHA-512 y la sal de antes:

public static function hashValue($str) {
    for ($x = 0; $x < 10000; $x++) {
        $str = hash('sha512', $str . self::$salt);
    }

    return $str;
}

Si todo es correcto, $_SESSION[$sessionkey] se establece con el ID de usuario de la base de datos (aunque la clave de la sesión larga no debería ser necesaria porque el cliente no puede cambiar el $_SESSION vars localmente, IIRC. ¿Verdad? )
Si el sitio está protegido (como en, los usuarios que no han iniciado sesión no tienen acceso) se llama a este código para redirigirlos de nuevo al índice si no han iniciado sesión:

if (!isset($_SESSION[$sessionkey])) {
    header("Location: ?view=default");
    exit;
}

¿Esta aplicación es segura? He leído en alguna parte que es mejor tener un archivo sal generado aleatoriamente para cada usuario, guardado en la base de datos. ¿Es realmente necesario, teniendo en cuenta que solo previene el brute forzando un poco mejor, lo que no debería ser un problema con un captcha de todos modos?

    
pregunta nn3112337 12.02.2016 - 11:02
fuente

1 respuesta

23

El peor escenario del que tiene que protegerse es un atacante que comprometa completamente su servidor y obtiene su código fuente, su configuración y un volcado de su base de datos. Ten eso en cuenta.

Este es el escenario en el que se supone que un salt protege sus contraseñas. La fuerza bruta remota no se ve afectada por una sal en absoluto (lo cual no tiene sentido en todo, excepto en las contraseñas más triviales debido al ancho de banda limitado de la red).

Algunos problemas:

  • Una "sal" que es la misma para todas las contraseñas se llama pepper y no aumenta la seguridad mucho cuando el atacante lo sabe.
  • SHA512 es un algoritmo de resumen de mensajes, no un algoritmo para hashing de contraseñas. El problema con SHA512 es que es demasiado rápido, lo que permite al atacante forzar con gran fuerza la base de datos de contraseñas robadas muy rápidamente. Lo que quieres es un algoritmo intencionalmente lento como bcrypt. PHP tiene una implementación predeterminada muy fácil de usar que puede generar, almacenar y aplicar automáticamente la sal para usted.
  • Los identificadores de sesión largos, únicos e imposibles de adivinar son necesarios , porque cuando un atacante puede adivinar el identificador de la sesión de un usuario registrado, puede secuestrar su sesión. El sistema de manejo de sesiones de PHP asume que cualquier solicitud que incluya el ID de sesión de un usuario previamente autenticado proviene de ese usuario autenticado. En general, debe confiar en los ID de sesión generados automáticamente por PHP y reemplazarlos solo con los suyos cuando esté seguro de que sabe lo que está haciendo.
  • Punto menor: "Después de eso, me conecto a la base de datos, escapa todas las cadenas y leo los datos". Escapa de todas las entradas del usuario con mysqli_real_escape_string sería suficiente en teoría , pero en la práctica es fácil de olvidar Algunos casos excepcionales en los que las cadenas proporcionadas por el usuario terminan en consultas de base de datos. Una práctica mejor es realizar todas las consultas de la base de datos con declaraciones preparadas que usan ? marcador de posición y bind para todas las variables. En ese caso, la API mysqli hace el escape para usted, que es mucho más confiable, especialmente porque es consciente del contexto en el que se utilizarán las cadenas escapadas. Como beneficio adicional, también tiene algunas ventajas de rendimiento y legibilidad.
respondido por el Philipp 12.02.2016 - 11:21
fuente

Lea otras preguntas en las etiquetas