Symfony Codificación de Contraseñas, Hashing y Protección CSRF
En el dinámico entorno de la seguridad cibernética, la protección de contraseñas es más que una buena práctica; es una necesidad imperativa. Symfony, el robusto framework de PHP para aplicaciones web, ofrece un enfoque sofisticado para la codificación de contraseñas que merece ser explorado en detalle.
Además de la codificación de contraseñas, un elemento vital en la seguridad de aplicaciones web es la protección contra ataques de tipo Cross-Site Request Forgery (CSRF). Symfony ofrece una solución integrada para esto a través de su csrf_token_generator
.
Configuración de Hashers de Contraseñas en Symfony
La configuración de los hashers de contraseñas en Symfony es una tarea sencilla, pero con profundas implicaciones de seguridad. La definición de estos hashers se realiza en el archivo security.yaml
, un archivo de configuración que actúa como el núcleo de las definiciones de seguridad en Symfony.
# config/packages/security.yaml security: password_hashers: App\Entity\User: algorithm: auto cost: 12
En este ejemplo, hemos especificado que para la entidad User
, Symfony debe utilizar un algoritmo de hashing «auto», que seleccionará el algoritmo más fuerte y adecuado disponible, y un «coste» que define la complejidad del hashing, equilibrando seguridad y rendimiento.
Migración entre Algoritmos de Hashing
Una característica particularmente potente de Symfony es su capacidad para manejar la migración entre diferentes algoritmos de hashing sin problemas. Esto significa que puedes actualizar tus métodos de codificación sin temor a perder la compatibilidad con las contraseñas existentes.
// config/packages/security.php use Symfony\Config\SecurityConfig; return static function (SecurityConfig $security): void { $security->passwordHasher('App\Entity\User') ->algorithm('sodium') ->migrateFrom([ 'bcrypt', 'legacy', ]); };
Aquí, Symfony está configurado para usar sodium
para las nuevas contraseñas, pero aún puede verificar y rehash las contraseñas que se crearon con bcrypt
o un hasher ‘legacy’.
Automatización del Rehashing
Una vez que un usuario con una contraseña antigua se autentica con éxito, Symfony no solo verifica la contraseña con el antiguo algoritmo, sino que también la actualiza automáticamente con el nuevo algoritmo, almacenando el hash actualizado en la base de datos.
Implementación de PasswordUpgraderInterface con Doctrine
Para los desarrolladores que utilizan Doctrine, Symfony proporciona PasswordUpgraderInterface
, que se puede implementar en el UserRepository
para gestionar el almacenamiento de hashes de contraseña recién creados de manera eficiente.
// src/Repository/UserRepository.php namespace App\Repository; use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; class UserRepository implements PasswordUpgraderInterface { public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void { // set the new hashed password on the User object $user->setPassword($newHashedPassword); // execute the queries on the database $this->getEntityManager()->flush(); } }
Este método upgradePassword
es fundamental para garantizar que las contraseñas de los usuarios siempre se almacenen con el hash más seguro disponible.
¿Qué es CSRF y por qué es importante?
CSRF es un ataque que engaña al navegador de un usuario para que ejecute acciones no deseadas en una aplicación web en la que están autenticados. Symfony contrarresta este riesgo mediante el uso de tokens CSRF, que son tokens únicos y secretos generados para cada usuario, asegurando que las solicitudes enviadas al servidor sean legítimas y autorizadas.
Configuración del CSRF Token Generator
En Symfony, configurar un csrf_token_generator
es sencillo y puede integrarse perfectamente con el sistema de formularios y otras partes de la aplicación que requieran protección CSRF.
# config/packages/security.yaml security: csrf_token_generator: security.csrf.token_manager
Aquí, hemos especificado que Symfony debe usar el servicio security.csrf.token_manager
como nuestro generador de tokens CSRF, lo cual se encarga de la creación y validación de estos tokens.
Uso de Tokens CSRF en Formularios
Los formularios son uno de los componentes más comunes que necesitan protección contra CSRF. Symfony facilita la integración de tokens CSRF en formularios, asegurando que cada formulario enviado se acompañe de un token válido.
{{ form_start(form) }} {{ csrf_token('authenticate') }} // ... campos del formulario ... {{ form_end(form) }}
En este ejemplo de Twig, se muestra cómo agregar un token CSRF a un formulario, utilizando la función csrf_token
.
Sincronización de Seguridad: Hashing de Contraseñas y Tokens CSRF
Symfony va más allá al sincronizar el sistema de seguridad. Mientras gestiona el hashing de contraseñas como se describió anteriormente, también asegura que los tokens CSRF estén en línea con las sesiones de usuario y su autenticación. Esto significa que la seguridad de las credenciales y la integridad de las sesiones se manejan en conjunto, proporcionando una barrera sólida contra posibles vulnerabilidades.
Conclusión: Seguridad en Capas con Symfony
Symfony no solo se centra en una sola faceta de la seguridad, sino que proporciona un enfoque en capas. La codificación de contraseñas y la generación de tokens CSRF son solo dos ejemplos de cómo Symfony se asegura de que los aspectos fundamentales de la seguridad estén cubiertos. Al aprovechar estas herramientas, los desarrolladores pueden construir aplicaciones seguras que están protegidas contra una amplia gama de ataques y vulnerabilidades.
Una pregunta, tengo 2 entornos en mi proyecto Symfony el de PRE y PRO.
Cuando comparto la base de datos e intento loguearme en la aplicación me sale el error de Invalid credentials en Symfony. ¿ A que puede deberse si el proyecto es identico?
Revisa la configuración de tu sistema operativo del servidor, seguramente la clave la esté cogiendo de una variable de entorno que tengas configurada en tu servidor, o depende de alguna biblioteca DLL que tengas diferente, o alguna configuración diferente en tu php.ini
Revisa esos aspectos y quizás des con la clave.
Gracias por comentar.