2009-03-03 17 views
11

Después de publicar this hace un tiempo, decidí crear mi propia capacidad de Registro/Autenticación en PHP. Me encantaría que cualquiera pueda señalar los defectos/oportunidades de mejora, particularmente alrededor de lo que está almacenado en la sesión ...Critique mis esfuerzos de autenticación de PHP

El flujo lógico es:

1 - usuario se registra utilizando el correo electrónico como nombre de usuario, un "sitio nombre "que luego forma parte de cualquier url a la que tendrán acceso y una contraseña de al menos 6 caracteres que deben contener letras y números (sé que esto podría ser más fuerte)

2 - Siempre que el usuario y el sitio sean únicos , Luego almaceno ambos, junto con una cadena (sal) generada aleatoriamente en una fila en la tabla de autenticación en mi base de datos. Luego tomo la contraseña de los usuarios, concateno la sal y almaceno un hash md5 de esta contraseña salada en la misma fila de base de datos

3 - Cuando un usuario inicia sesión, tomo la contraseña que ha ingresado y concateno la sal para ello, crea un hash md5 de eso, y compáralo con lo que he almacenado en la base de datos; si coinciden, el usuario ha ingresado la contraseña correcta y su nombre de usuario está escrito en la sesión

4 - En cada solicitud, utilizo el nombre de usuario almacenado en la sesión para consultar la base de datos y leer el nombre del sitio asociado con este usuario. Luego comparo esto con el nombre del sitio en la url misma, y ​​si coinciden establezco una variable que es accesible para el resto o la secuencia de comandos (no es una variable global, es solo legible por mi controlador que decide si un usuario puede ver una página en particular) si los dos nombres de sitios no concuerdan, el usuario es redirigido de nuevo al inicio de sesión

Mi preocupación es que alguien escriba en la sesión y así pueda acceder a las páginas de personas si conocen el nombre de usuario que firmaron arriba con? ¿Cómo harías para prevenir esto?

Antes de que nadie me acuse de negligencia por la forma en que este es un proyecto personal de aprendizaje, ¡no expongo datos de ningún cliente!

+0

Debe volver a utilizar un marco de autenticación existente siempre que sea posible, porque, en realidad, es complejo. Por ejemplo, eche un vistazo a https://github.com/delight-im/PHP-Auth, que es tanto agnóstico como independiente de la base de datos. – caw

Respuesta

1

Si alguien está mirando el envío del formulario de registro, entonces ellos tienen la información que le preocupa que descubrirán. Primer paso: use HTTPS para sus formularios.

En cuanto a las cosas de db cifradas, dejaré que otra persona tenga problemas. :-)

8
  1. ¿Por qué 6 caracteres? Hazlo más grande y requiere un mínimo de 6 (o más) caracteres. No hay excusa para limitar el número de caracteres de la contraseña a 6.

  2. Ponga más que el nombre de usuario en la sesión. Pero para hacer esto de forma segura, debe cambiar la sal cada inicio de sesión:

A- Desde la página de inicio de sesión: tome el nombre y la contraseña verifique con sal existente. Si es válido, actualice la sal y la contraseña de la tabla de usuario con una nueva sal (tiene la contraseña del usuario para que pueda md5 y sal). Escriba el md5 de la contraseña para la sesión. B- Desde cualquier otra página: compare el usuario y la contraseña hash contra la base de datos. Si no coinciden, redirija a la página de inicio de sesión.

El error con esta idea es que el usuario no puede mantener los inicios de sesión en varias máquinas/navegadores.

Su sistema de registro necesita trabajar para. ¿Cómo sabes que la dirección de correo electrónico es válida?¿Cómo sabes que el usuario que registra posee la dirección de correo electrónico? Debe enviar un correo electrónico a la dirección que contiene un enlace a su sitio web al que debe hacer clic antes de permitir que la cuenta acceda a algo. De lo contrario, alguien puede inscribirse bajo la dirección de correo electrónico de otra persona y realizar reclamos fraudulentos como esa persona o simplemente hacer que su sitio envíe spam a la persona que cierra el sitio.

También es posible que desee investigar CAPTCHA para limitar los registros con guiones.

+0

Gracias Joe - Re 6 charachters, ya es al menos 6 en lugar de exactamente 6, voy a editar para aclarar. Al escribir la contraseña para la sesión, ¿la idea es escribir algo diferente cada vez, de modo que los datos robados de la sesión solo sean buenos hasta que se vuelva a iniciar sesión? –

+0

Sí. De lo contrario, alguien puede reutilizar la sesión para siempre (o hasta que el usuario cambie su contraseña. Algunos dirán que el valor debería cambiar en cada página, pero luego debe almacenar la contraseña sin procesar en la sesión. Eso tiene menos sentido para mí. – jmucchiello

3

Respuesta corta: se ve bien!

Respuesta larga:

  1. Sí, usted debe permitir contraseñas más seguras/más largos, pero por lo demás está bien. Solo asegúrese de aceptar solo caracteres válidos de parte de url (me quedaría con los caracteres de palabra de PCRE) para el nombre del sitio. Sin embargo, un sistema de "validación de este correo electrónico" sería apropiado para garantizar que el registrante realmente controle la dirección de correo electrónico proporcionada.
  2. Se ve bien. Sin embargo, me gusta sha1 mejor que md5.
  3. Siempre que sus sesiones sean seguras, puede almacenar más que solo el nombre de usuario (lo que sería una búsqueda bastante costosa para SQL para cada solicitud de página - adelante y almacene su PK).
  4. Se ve bien, pero debe ajustarse por mis comentarios en el # 3

Para asegurarse de que está manejando su seguridad de sesión correctamente, compruebe the guide on PHPSec.

3
  • Limite la velocidad en los inicios de sesión. Registre cada intento para un usuario y bloquéelos después de tantos intentos fallidos. A medida que aumentan los intentos fallidos, haga que el bloqueo sea más largo y más largo.

  • Agregue un sal en su código que sea estático y úselo en combinación con la sal de la base de datos. Entonces, si db es pirateado, todavía no tienen la sal del código. Esta sal no puede/no debe cambiar.

  • ¿Pueden los usuarios recuperar contraseñas/restablecer los bloqueos? Necesitarás recolectar preguntas y respuestas de desafío.

  • Cuando los usuarios restablecen sus contraseñas, ¿tienen que conocer la original?

Si este es un sitio seguro, o simplemente un sitio que rastrea a alguien. Sé de sitios en los que puede llevar su cookie de máquina a máquina para iniciar sesión. Siempre te recuerda, pero es solo un foro, por lo que el potencial de problemas es bajo.

¿Por qué incluir el código y la base de datos? Una vez que ha pirateado su base de datos, su sitio es pan comido. Sin embargo, ver que los usuarios tienden a usar la misma contraseña en muchos sitios, no tiene sentido ayudar a piratear la propiedad de todos. Si obtienen tu código también, entonces ocurre el jodido real, pero dejaremos tantas barreras como podamos.

La seguridad a través de la oscuridad es tonta, pero muchas capas de seguridad pueden ayudar.

En cuanto a poner nombre de usuario en la sesión Hash el nombre de usuario, url y una sal. Almacene eso en la base de datos y en la sesión. utilízalo como autenticación, si eso no es válido, transfiéralos al inicio de sesión. no pueden copiar la cookie a otro sitio, no expondrán tanto su nombre de usuario y eliminarán una consulta.

Incluso puede regenerar ese valor salado cada X visitas de páginas y almacenar en la sesión para caducar y hacer que el robo sea menos útil con el tiempo. Luego almacenaría dos sales en su base de datos. Uno para la contraseña, uno para el valor de la sesión de autenticación.

+0

Tengo que decir , aunque lo que dices en tu segunda viñeta es cierto, una vez que la base de datos ha sido pirateada, el juego ya está listo, no? = P –

+0

Recuperar contraseña: una nueva se envía por correo electrónico a la dirección del usuario y se ve obligada a cambiar en el siguiente inicio de sesión Los usuarios necesitan saber p/w existente para cambiar –

+0

Actualizado mis pensamientos sobre salar el código – MrChrister

0

Si obtengo el flujo correcto, entonces si conozco su nombre de usuario y nombre de sitio, vaya al nombre del sitio y le doy una cookie con el nombre de usuario (ya que las sesiones, después de todo, se guardan como cookies), estoy in - ¿no se necesita contraseña? ¿No es eso un defecto?

+0

He visto esto, y por lo que puedo ver, la ID de sesión es almacenado como una cookie, pero ninguna de las variables en él? –

+0

Tu cuarto punto decía que "En cada solicitud, utilizo el nombre de usuario almacenado en la sessio n "(que puede ser falsificado) y luego compare esto con el nombre del sitio en la url misma. Entonces, si los forro a los dos, estoy dentro. – Liorsion

1

Mi preocupación es que alguien pueda escribir en la sesión, y así poder acceder a las páginas de personas si saben el nombre de usuario con el que se registraron? ¿Cómo harías para prevenir esto?

No estoy seguro de lo que quiere decir. ¿Cómo alguien "escribiría en la sesión"? La sesión es [generalmente] un archivo almacenado en el servidor que el cliente no puede ver o modificar.

Si le preocupa el secuestro de sesión (también conocido como fijación), debe habilitar SSL y deshabilitar las ID de sesión en la cadena URL. (Véase de php.ini session.use_only_cookies)

4 - En cada petición, yo uso el nombre de usuario almacenado en la sesión para consultar la base de datos y leer el nombre del sitio asociado con este usuario. Luego comparo esto con el nombre del sitio en la url misma, y ​​si coinciden establezco una variable que es accesible para el resto o la secuencia de comandos (no es una variable global, es solo legible por mi controlador que decide si un usuario puede ver una página en particular) si los dos nombres de sitio no coinciden, el usuario se redirige de nuevo al inicio de sesión

Esto parece la mayor preocupación. ¿Cómo se ve el nombre del sitio? ¿Cómo exactamente lo estás haciendo coincidir con la URL? Con una expresión regular?

Algunos detalles más sobre este aspecto serían buenos, porque si su control de acceso es defectuoso, entonces la calidad de su autenticación no importa demasiado.

Cuestiones relacionadas