FlawOpen

flawopen.com/Teardowns/cve-2026-104286-fortimail-ibe-path-traversal

● CVE-2026-104286 · CVSS 9.8[7] · Crítica
Investigación · FlawOpen

CVE-2026-104286: path traversal en FortiMail IBE

CVE-2026-104286 permite que solicitudes HTTP(S) sin autenticar escriban archivos en FortiMail vulnerable mediante path traversal. Fortinet informa de explotación activa; desactiva IBE o restringe el acceso web, investiga y actualiza.[1], [5]

💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina una sala de correo donde un empleado archiva adjuntos. El fallo permite que una solicitud le dé una ruta engañosa y escriba un archivo fuera del área prevista. La mitigación cierra la puerta de IBE o limita quién puede acceder a la interfaz web mientras se actualiza y se comprueba si ya hubo acceso.[1], [5]

Conceptos Clave y Términos

Path traversal (CWE-22)
Componentes de ruta no confiables escapan del directorio destinado a la operación. Fortinet describe escritura arbitraria de archivos en sistemas FortiMail afectados.[1], [6]
Identity-Based Encryption (IBE)
Función de FortiMail para flujos de correo cifrado. La mitigación temporal del proveedor es desactivar IBE; evalúa su impacto operativo.[1], [5]
CISA KEV
CISA añadió CVE-2026-104286 a KEV el 1 de octubre de 2026. Esto confirma explotación conocida, no que un dispositivo concreto haya sido comprometido.[2], [5]
Discrepancia de versiones
El resumen de Fortinet y avisos oficiales enumeran las ramas 7.2, 7.4, 7.6 y 8.0; los datos CNA también incluyen 7.0. Confirma esa rama con Fortinet.[6], [5], [4]

Mapeos de marcos

Análisis de Causa Raíz

Fortinet describe CVE-2026-104286 como una falla de path traversal que permite escribir archivos sin autenticación mediante solicitudes HTTP o HTTPS. El firmware es cerrado y el aviso público no contiene las líneas vulnerables ni el diff del parche; este artículo no los inventa. Los avisos oficiales confirman el impacto de escritura arbitraria, la explotación y las indicaciones de versiones, pero no describen el manejador interno de FortiMail. El aviso de Fortinet es la fuente de la medida temporal de desactivar IBE o restringir el acceso web y de los IOCs publicados. Contén e investiga el dispositivo y después instala la versión corregida adecuada; no encontrar un IOC no demuestra que sea seguro. La descripción en prosa del registro CVE enumera 7.2.0–7.2.9, 7.4.0–7.4.8, 7.6.0–7.6.6 y 8.0.0–8.0.1. La tabla estructurada del mismo registro fija límites superiores menores para 7.4 y 7.6 y también incluye 7.0.0–7.0.9, a diferencia de los resúmenes oficiales. La sección de soluciones del registro enumera versiones futuras inferiores —7.4.8, 7.6.6, 8.0.1 y 7.2.10—, en conflicto con sus propios datos de versiones afectadas y con el aviso canadiense del 1 de octubre. Usa ese aviso oficial fechado como guía operativa publicada y confirma con Fortinet la disponibilidad vigente y el alcance de 7.0; no deduzcas una versión corregida de los campos CNA contradictorios.[1], [3], [5], [4], [6], [7]

Matriz operativa: versiones y respuesta inicial

ÁreaQué indican las fuentes oficialesAcción defensiva
FortiMail 7.0Los datos de NVD/CNA incluyen 7.0.0–7.0.9; los resúmenes oficiales de Canadá y Francia no mencionan la rama 7.0. El mismo registro también discrepa entre la descripción y la tabla sobre los límites superiores de 7.4 y 7.6. La sección de soluciones también enumera versiones futuras inferiores (7.4.8, 7.6.6, 8.0.1 y 7.2.10), en conflicto con los rangos afectados y el aviso canadiense.Pide confirmación a Fortinet; no deduzcas que una rama omitida es segura.
FortiMail 7.2El aviso canadiense recomienda actualizar a la rama 7.4 o posterior.Planifica la migración a una rama compatible corregida; no supongas que existe un parche para 7.2.
FortiMail 7.4 / 7.6 / 8.0El aviso canadiense fija las correcciones en 7.4.9, 7.6.7 y 8.0.2, respectivamente.Usa el aviso canadiense AV26-989 como guía publicada de versiones; confirma disponibilidad y soporte en el aviso vigente de Fortinet antes de actualizar. No uses los límites inferiores de la sección CNA sin confirmación.
Contención e investigaciónFortinet informa de explotación y publica indicadores de compromiso; su medida temporal es desactivar IBE o restringir el acceso web.Conserva las pruebas, aplica la medida temporal, revisa los indicadores del proveedor, actualiza y evalúa si hubo compromiso.

Flujo de Ataque Paso a Paso

Paso 1

Una solicitud sin autenticar alcanza el flujo web

Fortinet indica que solicitudes HTTP o HTTPS especialmente construidas pueden activar el fallo sin credenciales. El aviso público no revela el controlador interno ni la implementación exacta.[1], [5], [4]

Paso 2

La ruta sale del límite previsto

El proveedor clasifica el problema como path traversal (CWE-22), que permite escribir archivos en el FortiMail afectado. No deduzcas persistencia concreta solo por la descripción del CVE.[1], [6], [5]

Paso 3

Los archivos escritos pueden ampliar el impacto

Fortinet asigna CVSS 3.1 9,8 Crítico e informa de explotación activa. Usa los IOC vigentes del proveedor para investigar.[1], [5], [4]

Paso 4

Mitiga, conserva pruebas y actualiza

Desactiva IBE o restringe el acceso web a redes confiables. Conserva registros y configuración, consulta los IOC e instala la versión corregida de la rama.[1], [5]

Código Fuente: Vulnerable vs. Seguro

El firmware de FortiMail y el diff del parche del proveedor no son públicos; este es un patrón genérico de defensa en Python, no código de Fortinet ni una reproducción. Abre una vez un directorio de confianza, usa un nombre opaco generado por el servidor y crea un archivo nuevo relativo al descriptor de ese directorio con creación exclusiva y opciones que no siguen enlaces. Es específico de POSIX y falla de forma segura si faltan las opciones necesarias. Para rutas anidadas, recorre un componente validado cada vez mediante descriptores de directorio; no compruebes una ruta textual para luego volver a abrirla por nombre. Para corregir CVE-2026-104286, aplica la actualización o mitigación oficial de Fortinet. Todos los componentes de la ruta raíz configurada, incluidos sus directorios padre, deben permanecer bajo control administrativo; O_NOFOLLOW solo protege el componente final al abrir esa raíz.

IMPLEMENTACIÓN VULNERABLE
from pathlib import Path

def destination(root: Path, request_path: str) -> Path:
    # Diseño inseguro ilustrativo: se une la entrada
    # sin comprobar que siga bajo la raíz permitida.
    return root / request_path
PARCHE SEGURO Y ROBUSTO
import os
import uuid

# Abre una vez el directorio confiable del servicio; sus directorios padre deben quedar bajo control administrativo.

def open_upload_root(root):
    required = ("O_DIRECTORY", "O_NOFOLLOW")
    if not all(hasattr(os, flag) for flag in required) or os.open not in os.supports_dir_fd:
        raise RuntimeError("POSIX directory protections unavailable")
    flags = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW
    return os.open(root, flags)

# No conviertas una ruta de la petición en ruta de archivo; genera un nombre opaco.
# O_EXCL falla si el nombre existe; O_NOFOLLOW rechaza un enlace simbólico final.
ROOT_FD = open_upload_root("/srv/app-private/uploads")


def create_upload_file():
    name = uuid.uuid4().hex
    flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW
    fd = os.open(name, flags, 0o600, dir_fd=ROOT_FD)
    return name, fd

Lista de Verificación de Seguridad para Ingeniería

Fuentes