Principales conclusiones
- Un ataque a Packagist ocurrido en mayo de 2026 demostró que el número de versión por sí solo no basta para garantizar que una instalación de Composer sea segura.
- Laravel 13 es totalmente compatible; Laravel 12 solo recibe correcciones de seguridad, y todas las versiones anteriores han llegado al final de su ciclo de vida.
- La vulnerabilidad CVE-2026-48019 afecta a todas las versiones de Laravel anteriores a la 12.60.0, así como a las versiones de Laravel 13 anteriores a la 13.10.0.
- La mayor parte del riesgo de Laravel reside en las exclusiones, las consultas sin procesar y las dependencias que nadie ha actualizado.
La seguridad de Laravel tiene menos que ver con el framework y más con lo que ocurre tras instalarlo. Una configuración predeterminada desactivada, una consulta sin filtrar o una dependencia que nadie haya actualizado suelen bastar para abrir una brecha de seguridad.
Esta guía repasa las amenazas que siguen llegando al entorno de producción, las prácticas que permiten solucionarlas, cómo proteger tus API y qué hacer si te ves obligado a seguir utilizando una versión obsoleta.
Por qué es importante la seguridad en las aplicaciones de Laravel
Una sola brecha de seguridad puede echar por tierra años de confianza de los clientes, acarrear responsabilidades legales y proporcionar a los atacantes las credenciales del servidor que les dan acceso a todo lo demás que gestionas. Y la forma de acceder al sistema ha cambiado. El Informe DBIR de Verizon de 2026 reveló que el aprovechamiento de una vulnerabilidad es ahora el vector de acceso inicial más común en las brechas de seguridad, presente en el 31 % de ellas, frente al 20 % del año anterior, mientras que el uso indebido de credenciales se redujo al 13 %.
Laravel elimina de raíz toda una serie de problemas desde el primer momento. Eloquent parametriza los valores de las consultas, Blade escapa la salida de forma predeterminada y el middleware contra la falsificación de peticiones (RFF) se incluye en el grupo «web» sin que nadie lo haya solicitado. Nada de eso se mantiene si un desarrollador decide desactivarlo, y nada de ello cubre la autorización, los errores de configuración, la falsificación de peticiones del lado del servidor, la lógica de negocio ni las dependencias vulnerables. Esas siguen siendo tu responsabilidad, de forma permanente.
Amenazas de seguridad habituales en Laravel
Scripting entre sitios a través de una salida de Blade sin escapar
De Blade’s {{ }} escapa automáticamente la salida. El {!! !!} no lo hace, y es a lo que recurre la gente cuando necesita mostrar código HTML almacenado procedente de un campo de un CMS o de un editor de texto enriquecido.
Si ese código HTML almacenado incluye una etiqueta de script, se ejecutará en el navegador de todos los usuarios que carguen la página. Límpialo primero en el servidor, con una biblioteca como HTMLPurifier, antes de que llegue a {!! !!}.
Inyección SQL a través de expresiones sin procesar
Eloquent y el generador de consultas parametrizan los valores de las consultas, por lo que la inyección no supone un problema en las consultas habituales. El problema surge en cuanto la entrada del usuario se concatena en DB::raw(), whereRaw(), havingRaw(), o orderByRaw().
Los nombres de columnas y direcciones suelen ser el error más común, ya que no se pueden pasar como parámetros. En su lugar, inclúyelos en una lista de permitidos comparando con una matriz fija. Tampoco es algo específico de Laravel. Es el mismo error que los desarrolladores de PHP llevan cometiendo desde hace veinte años al construir sentencias SQL con cadenas de caracteres.
Errores en la autenticación y la gestión de sesiones
La estructura de autenticación de Laravel es sólida. Los fallos se producen en torno a ella: no hay limitación de frecuencia en el inicio de sesión, los tokens de restablecimiento nunca caducan, las sesiones no se regeneran tras un cambio de privilegios y los flujos personalizados de cambio de contraseña omiten la llamada a `setRememberToken`, lo que hace que las sesiones con la opción «Recordarme» sigan siendo válidas tras el cambio de contraseña.
Comprueba la autorización por separado de la autenticación. Un inicio de sesión que funcione y que permita a cualquier usuario autenticado acceder a /admin constituye una vulnerabilidad de autorización, no un error en el formulario de inicio de sesión.
Buenas prácticas de seguridad en Laravel
1. Mantén actualizados Laravel y sus dependencias
Ejecutar «composer outdated» cada semana o cada dos semanas para ver qué paquetes tienen versiones más recientes y, a continuación, ejecuta «composer update» para instalarlos dentro de los límites que hayas establecido en composer.json. No pierdas de vista las notas de lanzamiento de Laravel y los avisos de seguridad de GitHub , ya que es ahí donde aparecen primero las vulnerabilidades del framework que acaban de darse a conocer.
La política actual de Laravel establece que cada versión cuenta con 18 meses de correcciones de errores y dos años de correcciones de seguridad a partir de su fecha de lanzamiento. Tampoco existe ya el nivel LTS. Laravel 6 fue la última versión de este tipo, y los plazos variaron durante la transición de versiones menores cada seis meses a versiones mayores anuales, por lo que las filas más antiguas que aparecen a continuación no siguen todas el mismo patrón.
| Versión | Fecha de publicación | Correcciones de errores hasta el | Correcciones de seguridad hasta el |
| 13 | Marzo 17, 2026 | Q3 2027 | Marzo 17, 2028 |
| 12 | Febrero 24, 2025 | Agosto 13, 2026 | Febrero 24, 2027 |
| 11 | Marzo 12, 2024 | Septiembre 3, 2025 | Marzo 12, 2026 |
| 10 | Febrero 14, 2023 | Agosto 6, 2024 | Febrero 4, 2025 |
| 9 | Febrero 8, 2022 | Agosto 8, 2023 | Febrero 6, 2024 |
| 8 | Septiembre 8, 2020 | Julio 26, 2022 | Enero 24, 2023 |
| 7 | Marzo 3, 2020 | Octubre 6, 2020 | Marzo 3, 2021 |
| 6 (LTS) | Septiembre 3, 2019 | Enero 25, 2022 | Septiembre 6, 2022 |
| 5.8 | Febrero 26, 2019 | Agosto 26, 2019 | Febrero 26, 2020 |
| 5.7 | Septiembre 4, 2018 | Marzo 4, 2019 | Septiembre 4, 2019 |
| 5.6 | Febrero 7, 2018 | Agosto 7, 2018 | Febrero 7, 2019 |
| 5.5 (LTS) | Agosto 30, 2017 | Agosto 30, 2019 | Agosto 30, 2020 |
| 5.4 | Enero 24, 2017 | Julio 24, 2017 | Enero 24, 2018 |
CVE-2026-48019 muestra lo que cuesta quedarse atrás. Se trata de una inyección CRLF en la regla de validación de correo electrónico predeterminada de Laravel que, combinada con la forma en que Symfony Mailer y Symfony Mime tratan ciertas secuencias de caracteres, permite a un atacante no autenticado manipular el correo saliente, introducir un encabezado Bcc, alterar el contenido del mensaje o convertir la aplicación en un relé. El aviso señala que todas las versiones anteriores a la 12.60.0 se ven afectadas, junto con Laravel 13 hasta la versión 13.9.0, y que las correcciones se han incorporado en las versiones 12.60.0 y 13.10.0. La ventana de seguridad de Laravel 11 ya se había cerrado en marzo de 2026, por lo que la versión 11 y todas las ramas anteriores se encuentran dentro de ese intervalo sin ninguna versión parcheada por parte del desarrollador original.
Si una actualización importante no es viable en este momento, el servicio de soporte de ciclo de vida ilimitado de TuxCare para Laravel retroporta correcciones de seguridad a través de Composer a versiones de referencia específicas, actualmente desde la 5.4.36 hasta la 12.58.0, con otras versiones disponibles bajo petición.
2. Tratar cada exclusión voluntaria de protección como una fase de revisión del código
Every Laravel security default ships with an escape hatch, and each one deserves a second pair of eyes before it goes out. {!! !!} in Blade turns off output escaping. DB::raw() and whereRaw() accept raw SQL, so any untrusted input has to arrive as a binding rather than concatenated into the string. Model::unguard(), $guarded = [],and Laravel 13’s #[Unguarded] attribute all open mass assignment on every column.
La protección contra la falsificación de solicitudes tiene su propia «vía de escape», y la API ha cambiado de ubicación. En Laravel 13, se excluyen las rutas con preventRequestForgery(except: […]) en bootstrap/app.php; en las versiones 11 y 12, el método se denomina validateCsrfTokens(), y en las versiones anteriores se utiliza el $except de la clase de middleware CSRF. Una ruta también puede excluirse pasando la clase de middleware de falsificación de peticiones correspondiente a withoutMiddleware().
Incorpora todo esto a una comprobación de integración continua (CI) basada en grep y haz que el autor de cualquier solicitud de incorporación de cambios que incluya alguno de estos elementos explique en la descripción por qué está ahí.
3. Validar en el lado del servidor y autorizar por separado
La validación comprueba si los datos están bien estructurados. La autorización comprueba si este usuario tiene permiso para actuar sobre ellos. El hecho de que uno se supere no implica nada respecto al otro.
Utiliza clases de solicitud de formularios para que las reglas de validación queden registradas en un lugar donde se puedan revisar, y utiliza «Policies» o «Gates» para cada acción del modelo. La validación del lado del cliente mejora la experiencia del usuario, pero no aporta absolutamente nada a la seguridad.
4. Configuración de seguridad y claves secretas
Establecer APP_DEBUG=false en el entorno de producción, sin excepción. La propia documentación de Laravel es muy clara sobre el riesgo de dejar activado el modo de depuración: los valores de configuración confidenciales pueden quedar expuestos a los usuarios finales, y la página de error de depuración muestra trazas de pila detalladas a quienquiera que haya provocado el error.
Guarda .env fuera del control de versiones y comprueba que la raíz de tu sitio web apunte a /public, y renueva APP_KEY si alguna vez se ha incluido en el control de versiones. Todos los valores cifrados y las cookies firmadas de la aplicación dependen de esa clave, así que incluye la clave antigua en APP_PREVIOUS_KEYS al realizar la rotación. Sin ella, los datos cifrados anteriormente ya no podrán descifrarse y todas las sesiones autenticadas se cerrarán.
5. Auditar las dependencias de forma periódica, no solo tras producirse incidentes
Ejecutar una auditoría de Composer en la integración continua (CI) para que un paquete con vulnerabilidades conocidas falle en la compilación, en lugar de aparecer en un informe trimestral.
composer audit –format=summary
Los paquetes oficiales de Laravel también reciben números CVE. CVE-2026-39976 era una vulnerabilidad que permitía eludir la autenticación en laravel/passport, corregida en la versión 13.7.1, en la que un token de «client_credentials» pudiera resolverse en una cuenta de usuario real. Solo supone un riesgo si se han desactivado los ID de cliente UUID, que es precisamente el tipo de detalle que se pasa por alto cuando un escáner solo te indica que un paquete ha sido marcado. Combina los escaneos programados con auditorías de seguridad y un proceso documentado para la aplicación de parches de vulnerabilidades.
Atención: Los días 22 y 23 de mayo de 2026, un un atacante volvió a publicar código malicioso bajo etiquetas de versiones históricas de cuatro paquetes de Laravel-Lang en Packagist. Todas las etiquetas existentes se redirigieron a un nuevo commit, por lo que el número de versión de tu archivo composer.json no te indicaba en absoluto qué se había instalado realmente. Para averiguar si te habías visto afectado, había que comprobar el commit resuelto en composer.lock, cuándo se ejecutaban tus compilaciones y los indicadores de compromiso publicados en ese momento.
Protección de las API de Laravel
La mayoría de las API son sin estado y se basan en tokens, lo que modifica el modelo de seguridad en lugar de simplemente debilitarlo. El navegador no adjunta automáticamente un token de portador como lo hace con una cookie de sesión, por lo que la protección contra CSRF deja de ser el control determinante. En su lugar, lo que cobra importancia es la autenticación, la autorización en cada acción, una política CORS que alguien haya configurado realmente, la limitación de frecuencia y el ciclo de vida del token. Las configuraciones con estado, como el modo SPA de Sanctum, son la excepción, ya que sí utilizan cookies de sesión y necesitan protección contra CSRF.
Sin embargo, hay algo que realmente falta. Nadie está ahí pendiente de las respuestas, por lo que una enumeración lenta realizada contra una API puede prolongarse durante días antes de que alguien se dé cuenta.
Elige «Sanctum» o «Passport» de forma deliberada
Sanctum gestiona la autenticación mediante tokens y SPA con una configuración mínima y se adapta a la mayoría de las aplicaciones. Passport implementa OAuth2 en su totalidad y solo resulta útil cuando realmente se necesitan flujos de autorización de terceros.
Cuanto mayor sea la superficie de Passport, mayor es el riesgo. Elijas lo que elijas, delimita bien el alcance de los tokens y establece fechas de caducidad. Un token sin fecha de caducidad sigue siendo válido hasta que alguien se acuerde de revocarlo, lo que hace que sea muy difícil contener una fuga de información.
Límite de solicitudes para cada punto de conexión público
El middleware de limitación de Laravel ocupa una sola línea, y es fácil olvidarse de incluirlo en una ruta de la API. Sin él, los ataques de «credential stuffing» y de enumeración se ejecutan a la velocidad que permita tu servidor.
Límite de solicitudes por usuario y por dirección IP, con restricciones más estrictas en el inicio de sesión, el restablecimiento de contraseñas y cualquier acción que implique el envío de correos electrónicos o SMS. Devolver un código de error 429 en lugar de fallar de forma silenciosa.
Refuerza la capa subyacente a tu aplicación
La seguridad de una API depende totalmente de la seguridad del servidor que la aloja. Activa el protocolo TLS, desactiva la visualización de directorios y aplica las actualizaciones del sistema operativo y del entorno de ejecución de PHP independientemente del ciclo de lanzamiento de Laravel.
La seguridad a nivel de aplicación no se mantiene si el servidor está comprometido. Hagas lo que hagas dentro del código de Laravel, el servidor subyacente debe reforzarse y actualizarse según sus propias necesidades.
Nota: Laravel 13 formalizó la protección contra la falsificación de solicitudes como PreventRequestForgery, que añade una comprobación del origen en el encabezado Sec-Fetch-Site del navegador, además de la validación habitual del token. Se permite una solicitud del mismo origen sin token, y cualquier solicitud que no supere la comprobación de origen pasa directamente a la validación del token. La documentación de Laravel señala que el encabezado solo se transmite a través de HTTPS, por lo que el HTTP sin cifrar sigue dependiendo por completo del token. Lee qué es lo que comprueba realmente el middleware antes de excluir nada de él.
Proveedores y soluciones de seguridad para Laravel
Soporte técnico de ciclo de vida ilimitado de TuxCare
ELS incorpora retroactivamente correcciones de seguridad a las versiones de Laravel que el equipo central ya no mantiene, y las distribuye a través de Composer, de modo que el flujo de trabajo de las dependencias no cambia. TuxCare también cubre los entornos de ejecución de PHP al final de su ciclo de vida , lo cual es importante cuando una aplicación antigua de Laravel también se ejecuta en una versión de PHP para la que el desarrollador original ha dejado de ofrecer parches.
ELS no es un sustituto de una actualización futura. Se trata de un soporte de seguridad a largo plazo para las ramas en las que el desarrollador original ha dejado de publicar parches, de modo que sigas recibiendo correcciones de CVE para una rama al final de su ciclo de vida (EOL) y puedas planificar la migración según tu propio calendario, en lugar de según el de otra persona.
Actualmente ofrecemos compatibilidad con estas versiones de Laravel: 5.4.36, 5.5.50, 5.6.40, 5.7.29, 5.8.38, 6.20.45, 7.30.7, 8.12.0, 8.12.1, 8.12.2, 8.12.3, 8.83.29, 9.52.21, 10, 11, 12.58.0.
Análisis de dependencias
Empieza por composer audit, ya que es gratuito y ya lo tienes instalado. Analiza los paquetes que tienes instalados, por lo que también incluye las dependencias transitivas, y composer audit –locked comprueba el archivo de bloqueo cuando no existe el directorio «vendor». Snyk, GitHub Dependabot y Aikido añaden a todo ello supervisión continua, alertas y solicitudes de actualización automatizadas, algo que merece la pena tener cuando nadie supervisa de cerca la integración continua (CI). Para un equipo más pequeño, Dependabot es una opción básica razonable. Lo que ninguno de ellos resuelve es el caso de un paquete al final de su vida útil (EOL), en el que, para empezar, no hay una versión fija a la que actualizar.
Protección y supervisión en tiempo de ejecución
Un cortafuegos de aplicaciones web solo sirve para ganar tiempo entre el momento en que se descubre una vulnerabilidad y se aplica el parche, nada más. Cloudflare, AWS WAF y ModSecurity, con un conjunto de reglas actualizado —como el OWASP Core Rule Set—, pueden bloquear muchas cargas útiles comunes de inyección y XSS antes de que lleguen a PHP, aunque la cobertura depende totalmente de las reglas que se activen. Combina el cortafuegos con la supervisión de registros para que un intento de explotación se distinga de una solicitud errónea habitual.
Protege tus aplicaciones Laravel con TuxCare
Mantener una aplicación de Laravel dentro de su ventana de soporte es donde los equipos se quedan atrás. Las actualizaciones importantes traen consigo cambios que rompen la compatibilidad, y compiten con el lanzamiento de nuevas funcionalidades en el mismo sprint. Si tu versión ha superado el fin de vida útil (EOL) y la migración no se va a llevar a cabo este trimestre, el servicio de soporte de ciclo de vida ilimitado de TuxCare para Laravel la mantendrá actualizada hasta que estés listo para dar el paso.



