CreaRack-SL

SSRF: mitigación en conexiones controlables por usuario (check_scan_ip)

Definición

Server-Side Request Forgery (SSRF) es una vulnerabilidad en la que una aplicación web hace una solicitud HTTP/TCP a una dirección controlada (parcialmente) por el usuario, sin validar si esa dirección es segura. Un atacante puede:

  • Forzar conexiones a servicios internos de la infraestructura (metadata cloud, bases de datos, servicios internos)
  • Escanear puertos de la red interna
  • Exfiltrar datos de hosts accesibles desde el servidor (pero no desde internet)

Riesgo en CreaRack Pro

En el módulo Digital Signage, hay 3 chokepoints donde se abren conexiones a direcciones controladas por el usuario (admin o cliente):

  1. Deploy WebDAV (monitoring/api/signage/deploy.py): abre conexión WebDAV a device.device_ip (IP del reproductor digital)
  2. Control de Display (signage/services/display_control/): abre socket TCP a la IP del dispositivo (Samsung MDC 1515, LG 9761, PJLink 4352)
  3. Adapters de vendor (signage/services/adapters/): hacen requests HTTP a URLs/IPs de reproductores o sistemas de terceros

Sin validación, un admin podría (por error o si está comprometido) apuntar un dispositivo a:

  • 169.254.169.254 — metadata cloud (AWS, GCP) → fuga de credenciales de infra
  • 127.0.0.1:5432 — PostgreSQL local → escaneo de puerto
  • 10.x.x.x — hosts internos de red — exfiltración de datos

Mitigación: check_scan_ip

CreaRack Pro hereda de network (sa1–sa5) un guard centralizado: check_scan_ip(ip_str) -> bool. Valida:

RangoPermitidoRazón
RFC1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)✅On-prem del cliente (uso legítimo)
CGNAT (100.64.0.0/10)✅On-prem del cliente (carrier NAT)
Loopback (127.0.0.0/8)❌SSRF al servidor mismo
Link-local (169.254.0.0/16)❌Metadata cloud (AWS, GCP)
Multicast (224.0.0.0/4)❌Ruido de red
Broadcast, reserved❌No encaminables

Aplicación en Signage (s121)

Antes:

# Vulnerable
def deploy_content_to_device(device_id, ...):
    device = SignagePlayer.objects.get(id=device_id)
    webdav_put(device.device_ip, ...)  # Sin validación

Después:

# Seguro
from network.services.security import check_scan_ip

def deploy_content_to_device(device_id, ...):
    device = SignagePlayer.objects.get(id=device_id)
    if not check_scan_ip(device.device_ip):
        raise ValidationError(f"IP {device.device_ip} no permitida")
    webdav_put(device.device_ip, ...)

Se aplica en:

  1. deploy_content_to_device — antes de WebDAV PUT
  2. display_control.controller — antes de abrir socket TCP
  3. adapters.registry.get_adapter — antes de hacer request HTTP

Casos de Uso Legítimos

  • Un cliente on-prem con dispositivos en 192.168.x.x puede seguir deployando
  • Un cliente con red local en 10.x.x.x puede seguir controlando displays
  • Un cliente CGNAT con 100.x.x.x puede seguir comunicándose

El guard preserva la funcionalidad legítima mientras bloquea ataques.

Referencias

  • OWASP A10:2021 — Server-Side Request Forgery (SSRF)
  • CWE-918 — Server-Side Request Forgery (SSRF)
  • PortSwigger: SSRF

Véase también

  • [[feature—signage—s121-permisos-rol-y-seguridad]]
  • [[entity—network—service—check-scan-ip]]
  • [[concept—saas—multi-tenancy]]