Problema
Muchos inquilinos de Microsoft Entra siguen confiando únicamente en “requerir MFA” como única defensa. Esa estrategia funciona contra credenciales robadas, pero no protege contra sesiones comprometidas, dispositivos no gestionados o accesos desde ubicaciones de alto riesgo. Cuando la superficie de ataque incluye aplicaciones SaaS, dispositivos BYOD y usuarios externos, una política basada solo en MFA deja brechas evidentes: accesos desde redes no confiables, uso de protocolos heredados y privilegios excesivos sin control adicional.
El patrón que se repite es la ausencia de un conjunto estructurado de políticas que cubra:
- Autenticación basada en riesgo de sesión.
- Restricciones de dispositivo y de red.
- Controles de sesión para aplicaciones críticas.
- Exclusiones y precedencias bien definidas.
Sin esas capas, los atacantes pueden evadir MFA mediante token hijacking, uso de dispositivos comprometidos o explotación de protocolos que no admiten MFA.
Causa
- Política heredada – La mayoría de los entornos fueron configurados cuando MFA era la única recomendación oficial. No se revisaron después de que Microsoft introdujo controles basados en riesgo y dispositivos.
- Falta de visibilidad de riesgos – Los administradores no habilitan la evaluación de “sign‑in risk” ni el registro de “device compliance”, por lo que el motor de Conditional Access no tiene datos para actuar.
- Dependencia de aplicaciones legacy – Protocolos como POP/IMAP o SMTP siguen habilitados, lo que obliga a mantener “legacy authentication” activo y, por ende, fuera del alcance de MFA.
- Gestión de invitados insuficiente – Los usuarios B2B a menudo reciben los mismos permisos que los internos sin restricciones de ubicación o de dispositivo.
- Políticas fragmentadas – Cada equipo crea reglas aisladas (por ejemplo, “MFA para administradores”) sin una arquitectura global, lo que genera solapamientos y excepciones inesperadas.
Solución
Construir un baseline de Conditional Access que cubra los ocho pilares siguientes. Cada pilar se implementa como una política independiente; el orden de evaluación se controla mediante la prioridad de “grant” y “session” y mediante exclusiones explícitas.
1. Bloquear autenticación heredada
- Objetivo: eliminar POP/IMAP, SMTP, IMAP, MAPI y cualquier flujo que no soporte MFA.
- Condición: All client apps → Legacy authentication protocols.
- Acción: Block.
2. Requerir MFA para cuentas privilegiadas
- Objetivo: proteger administradores, cuentas de servicio y roles de alto riesgo.
- Condición: User or group → Privileged role administrators (incluye Global Admin, Security Admin, etc.).
- Acción: Require multi‑factor authentication.
3. Exigir dispositivos gestionados o híbridos
- Objetivo: impedir accesos desde dispositivos no registrados o no compliant.
- Condición: Device state → Hybrid Azure AD joined o Compliant.
- Acción: Require MFA (como segunda capa) o Block si la política es estricta.
4. Aplicar MFA basada en riesgo de sign‑in
- Objetivo: activar MFA solo cuando el riesgo de la sesión supera un umbral.
- Condición: Sign‑in risk → Medium o High.
- Acción: Require MFA.
5. Control de sesión para aplicaciones críticas
- Objetivo: limitar la persistencia de tokens y forzar re‑autenticación frecuente.
- Condición: Cloud apps → Office 365, Azure Management, Power Platform.
- Acción: Use app enforced controls → Sign‑in frequency 8 h, Persistent browser session = Never.
6. Ubicaciones confiables y MFA fuera de ellas
- Objetivo: confiar en rangos de IP corporativos y exigir MFA para cualquier acceso externo.
- Condición: Location → All trusted IPs (named location) y Any location.
- Acción: Grant access si está dentro de la ubicación confiable; Require MFA si está fuera.
7. Restricciones para usuarios B2B
- Objetivo: evitar que invitados accedan sin controles de dispositivo o ubicación.
- Condición: User or group → All guest users.
- Acción: Require MFA + Require compliant device + Block legacy authentication.
8. Política de reporte (Report‑Only) para pruebas
- Objetivo: validar el impacto antes de bloquear.
- Condición: Copia de cada política anterior con Report‑Only activado.
- Acción: Grant access (sin bloqueo) y registrar eventos en los logs.
Implementación paso a paso (PowerShell)
- Conectar al módulo Microsoft Graph:
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"
- Crear la política de bloqueo de autenticación heredada:
$policy = @{
displayName = "Block legacy authentication"
state = "enabled"
conditions = @{
clientAppTypes = @("Other")
applications = @{
includeApplications = @("*")
}
clientAppTypes = @("ExchangeActiveSync","IMAP","POP","SMTP")
}
grantControls = @{
builtInControls = @("block")
}
}
New-MgConditionalAccessPolicy -BodyParameter $policy
- Repetir con los demás pilares, ajustando
conditionsygrantControlssegún la tabla anterior. La documentación de Microsoft Graph contiene la lista completa de propiedades.
Buenas prácticas de gestión
- Nombrado consistente: prefijo
Baseline-+ descripción (p.ej.,Baseline-RequireMFA-Privileged). - Prioridad: las políticas de bloqueo deben estar en la parte superior; las de reporte en la inferior.
- Exclusiones mínimas: evita excluir grupos completos; usa excepciones puntuales (p.ej., cuentas de servicio con certificados).
- Revisión trimestral: actualiza los rangos de IP y los criterios de riesgo según los informes de Azure AD Sign‑in logs.
Cuándo aplicar esta solución
Aplica cuando:
- El tenant tiene más de 100 usuarios activos y al menos un 20 % de ellos son externos o invitados.
- Se detecta uso de protocolos legacy en los logs de Azure AD.
- Los administradores reportan incidentes de token hijacking o acceso desde dispositivos no gestionados.
No aplica si:
- El entorno depende exclusivamente de un IdP externo que ya gestiona riesgos y dispositivos (p.ej., Okta con políticas propias) y no utiliza Azure AD como fuente de autoridad.
- La organización opera en una red aislada sin acceso a internet y no necesita controles basados en ubicación.
Código
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"
# Ejemplo: política que requiere MFA para usuarios con riesgo medio/alto
$policy = @{
displayName = "Baseline-RequireMFA-HighRiskSignIn"
state = "enabled"
conditions = @{
users = @{
includeUsers = @("*")
}
signInRiskLevels = @("high","medium")
}
grantControls = @{
builtInControls = @("mfa")
}
}
New-MgConditionalAccessPolicy -BodyParameter $policy
Verificación
- Lista de políticas – Ejecuta
Get-MgConditionalAccessPolicyy confirma que todas las políticas creadas aparecen constate = enabled. - Simulación de acceso – Usa la herramienta “What If” en el portal de Azure AD para probar combinaciones de usuario, dispositivo y ubicación.
- Revisión de logs – En Azure AD → Sign‑in logs, filtra por
Conditional Accessy verifica que los eventosgrantyblockcoinciden con las reglas definidas. - Prueba de legado – Intenta una conexión IMAP con una cuenta de prueba; debería resultar en
401 Unauthorized.
Notas adicionales
- Modo Report‑Only: siempre habilita una copia de cada política en modo reporte antes de pasar a producción; los logs revelan falsos positivos sin interrumpir usuarios.
- Excepciones de cuentas de servicio: si una aplicación necesita autenticación sin MFA, usa certificados o Managed Identities y exclúyela explícitamente en la política de MFA, pero mantén el bloqueo de legacy authentication.
- Monitoreo continuo: configura alertas en Azure Monitor para
ConditionalAccessPolicyconresult = failure; así detectas intentos bloqueados que puedan indicar un ataque