Saltar al contenido
>_ITDITDPlataforma de seguridad web

Por framework

Seguridad en ASP.NET Core — una referencia de endurecimiento para producción

Una referencia de endurecimiento para producción de ASP.NET Core: una lista de verificación por prioridad más errores de producción, secretos (User Secrets/Key Vault), CVE de NuGet, autorización, over-posting, deserialización y SSRF. Defensiva, sin pasos de ataque.

Publicado 2026-07-02 Actualizado 2026-07-02 7 min de lectura

Para: cualquiera que gestione una aplicación o API en ASP.NET Core. Aquí no hay pasos de ataque — esta es una referencia de trabajo para el endurecimiento: una lista de verificación ordenada por prioridad, guía por área y autoverificación. Para el panorama entre frameworks, consulta el centro de seguridad por framework.

Lista de endurecimiento ordenada por prioridad

Recorre esta tabla de arriba abajo. P0 es un prerrequisito, P1 es la fuente más frecuente de incidentes, P2 es higiene operativa continua.

P0 ── Prerrequisito (hazlo primero)

Sin errores detallados en producción / externalizar los secretos / parchear rápido los CVE de dependencias NuGet

P1 ── Principal fuente de incidentes

Autorización ([Authorize], denegación por defecto, propietario) / defensa contra over-posting (DTOs/[Bind])

P2 ── Higiene operativa

Deserialización insegura / HTTPS, cabeceras, antiforgery / SSRF

Endurece desde los cimientos hacia arriba: P0 (prerrequisito) → P1 (principal fuente de incidentes) → P2 (higiene operativa).
PrioridadControlDetalles (ASP.NET Core)
P0Errores de producciónUseExceptionHandler. No muestres la Developer Exception Page/detalle en producción (comprobación de entorno correcta)
P0Externalizar secretosNo los codifiques en appsettings.json. Desarrollo = User Secrets, producción = env/Key Vault
P0CVE de dependencias NuGetMonitoriza con dotnet list package --vulnerable/osv-scanner; juzga por la versión en ejecución, parchea rápido
P1Autorización explícita[Authorize] + denegación por defecto (política de reserva) + comprobaciones basadas en recurso/propietario
P1Defensa contra over-postingHaz binding a un DTO, no a la entidad directamente. Usa [Bind] para limitar los campos aceptados
P2DeserializaciónNo uses BinaryFormatter. No restaures datos no confiables con un formato inseguro
P2HTTPS/cabeceras/CSRFUseHttpsRedirection, UseHsts, antiforgery (CSRF), atributos de cookie
P2SSRFLista de permitidos para las peticiones del lado del servidor + bloquear IPs internas/metadatos

1. Exposición de errores en producción (P0)

  • En producción, cambia a un error genérico mediante UseExceptionHandler y no muestres la Developer Exception Page/detalle (acierta la comprobación de entorno, p. ej. ASPNETCORE_ENVIRONMENT=Production).
  • No filtres trazas de pila ni estructura interna externamente.

2. Externalizar secretos (P0)

  • No codifiques cadenas de conexión ni claves en appsettings.json. Usa User Secrets en desarrollo y variables de entorno o un gestor de secretos en la nube (Key Vault) en producción.
  • appsettings.json se filtra fácilmente mediante un commit accidental o exposición. No lo incluyas en el repositorio ni lo coloques en un directorio público (→ mantén los secretos fuera de los directorios públicos). Rota de inmediato si se filtra.

3. CVE de dependencias NuGet (P0)

4. Autorización (P1 — la principal fuente)

Común (peligroso)

  • olvidar [Authorize] en un endpoint
  • autenticado, pero sin comprobación de propietario
  • el valor por defecto se inclina a «permitir», los no autenticados pasan
  • sin diseño de roles/políticas, comprobaciones ad-hoc

Correcto

  • [Authorize] + denegación por defecto mediante una política de reserva
  • basada en roles/políticas + autorización basada en recurso para la propiedad
  • verificado en cada ruta de lectura/actualización/borrado
  • autorización construida explícitamente, no dejada a los valores por defecto

Consulta qué es el IDOR. La autenticación y la autorización son distintas; autoriza cerca de los datos.

5. Over-posting (P1)

  • No hagas binding a las entidades directamente. Haz binding a un DTO solo de entrada y acepta únicamente los campos que necesitas.
  • O usa [Bind] para limitar explícitamente los campos aceptados. No dejes que un flag de privilegio se sobrescriba desde la entrada externa.

6. Deserialización insegura y entrada (P2)

  • No uses BinaryFormatter (obsoleto/inseguro). No restaures datos no confiables con un formato inseguro (puede llevar a RCE en las condiciones adecuadas) (→ qué es el RCE).
  • Valida la entrada con validación de modelo (data annotations, etc.) para tipo/rango/valores permitidos antes de usarla.

7. HTTPS, cabeceras, antiforgery (P2)

  • Usa UseHttpsRedirection + UseHsts para forzar HTTPS, y marca las cookies como secure/httponly/samesite.
  • Usa tokens antiforgery (defensa CSRF) en formularios/peticiones que cambian estado (→ qué es el CSRF).
  • Añade cabeceras de seguridad (comprueba tu propio sitio con el verificador de cabeceras de seguridad).

8. SSRF y peticiones del lado del servidor (P2)

  • La obtención del lado del servidor (HttpClient, etc.) de URLs proporcionadas por el usuario debe restringir los destinos a una lista de permitidos y bloquear el alcance a IPs internas/metadatos (→ qué es el SSRF). Valida las subidas y almacénalas fuera de la superficie pública.

Verifica: ¿está tu ASP.NET Core realmente endurecido?

Construirlo no es el final — solo está hecho una vez que lo has comprobado. Estas son autocomprobaciones defensivas contra tu propio entorno.

1

Sin Developer Exception Page en producción

Provoca un error en producción y confirma que el detalle (traza / Developer Exception Page) no se muestra externamente.
2

Los secretos no están en la config/repositorio

Confirma que las cadenas de conexión/claves no están codificadas en appsettings.json, y que no hay secretos en el repositorio.
3

La autorización se sostiene

En un entorno de pruebas, solicita un recurso de otro usuario y confirma que se deniega (lectura/actualización/borrado).
4

Dependencias y HTTPS/cabeceras

Confirma que dotnet list package --vulnerable/osv está limpio, y que HTTPS/HSTS están presentes mediante el verificador de cabeceras.

La opinión de este sitio: aun sobre una base sólida, la configuración y la autorización dependen de ti

ASP.NET Core tiene mecanismos sólidos para la autenticación, la autorización y la protección de datos, pero la configuración de producción y aplicar la autorización son cosas que debes acertar por entorno y por endpoint. Este sitio usa una pila distinta, pero el principio es el mismo: no filtres detalles internos en producción, mantén los secretos fuera de la configuración, escribe siempre la autorización en los puntos de entrada públicos, y monitoriza las dependencias en busca de CVE. Una base sólida solo rinde con una configuración correcta y una autorización explícita.

Lee a continuación

FAQ

Q¿Qué debo hacer primero para asegurar ASP.NET Core?
A

Los tres elementos P0: (1) no muestres la Developer Exception Page / errores detallados en producción (UseExceptionHandler, comprobación de entorno correcta); (2) externaliza los secretos en lugar de codificarlos en appsettings.json (User Secrets en desarrollo, variables de entorno o Key Vault en producción); (3) monitoriza de forma automática los CVE de dependencias NuGet y parchea rápido, juzgando por la versión en ejecución. Luego, pasa a la autorización ([Authorize], denegación por defecto) y a las defensas contra over-posting.

Q¿Dónde deben ir los secretos (cadenas de conexión, claves de API)?
A

La regla es: no codificados en appsettings.json. En desarrollo usa User Secrets; en producción cárgalos desde variables de entorno o un gestor de secretos en la nube (Key Vault). appsettings.json tiende a acabar en el repositorio y se filtra fácilmente mediante un directorio público o un commit accidental. Si uno se filtra, rota la cadena de conexión o la clave de inmediato.

Q¿Cómo evito olvidar los atributos de autorización?
A

Olvida [Authorize] en un controlador o endpoint y cualquiera puede alcanzarlo sin autenticación. Inclina el valor por defecto hacia denegar (una política de reserva que rechaza las peticiones no autenticadas), haz los permisos explícitos con autorización basada en roles/políticas, y escribe comprobaciones de propietario del recurso (autorización basada en recurso). No te quedes en «con sesión iniciada = permitido» — verifica también al propietario del objetivo.

Q¿Qué es el over-posting?
A

Si el model binding acepta todos los campos en una entidad, campos inesperados que el usuario envió (como un flag de privilegio) pueden sobrescribirse — eso es over-posting. La solución es hacer binding a un DTO solo de entrada, o usar [Bind] para limitar explícitamente los campos aceptados. No hagas binding a las entidades directamente.

Q¿Por qué es peligrosa la deserialización insegura?
A

Restaurar datos no confiables con un deserializador inseguro como BinaryFormatter puede, en las condiciones adecuadas, llevar a la ejecución remota de código (RCE). BinaryFormatter se considera obsoleto/inseguro — no lo uses. Verifica la procedencia de los datos de origen externo y restringe a un formato seguro (p. ej. JSON correctamente configurado) donde sea necesario.