Volver a la wiki

Auditoría Suprema Etapa 3 · SA4 (ITSM/alerting) + SA5 (wireless/UPS) — Rectificación

Resumen

Tanda de rectificación de seguridad y correctness (Sesión 112, 2026-06-07) de las dos últimas sub-áreas auditadas del dominio monitoring:

Se cierran 18 hallazgos ALTA (todos de Broken Access Control sistémico) y la mayoría de hallazgos MEDIO. Sin cambios de base de datos; todas las fixes son a nivel de handler y lógica de negocio.


El problema central: Broken Access Control

Ninguno de los 89 handlers de itsm.py, itsm_runbooks.py, itsm_knowledge.py, itsm_groups.py, itsm_reports.py, alerts.py, wireless.py, ups.py comprobaba qué rol tenía el usuario autenticado.

Impacto: Un usuario con rol readonly (solo lectura) podía:

El único gate era estar autenticado (request.user.is_authenticated).

Fix principal

Añadido require_perm(request, scope, "view"|"edit") en los 89 puntos de control:

La función require_perm ya existía en core.utils (aplicada con éxito en SA1/SA2/SA6); ahora se generaliza a SA4/SA5.


Hallazgos ALTA corregidos

IDHallazgoCausaUbicaciónFix
sa4 A1, A3, A4, A6, A7, A8Broken Access Control: create/edit/delete SLA policies, channels, escalation, maintenance, runbooksSin require_permitsm.py (23 handlers)require_perm(request, "itsm", "view"/"edit") + require_org
sa5 A1-A9Broken Access Control: create/update/delete wireless, UPS, sentinel alertsSin require_permalerts.py (8 handlers), wireless.py, ups.pyrequire_perm(request, "observatory", "view"/"edit")
sa4 B4, M8; sa5 B7org=None en get_current_org → 500 en vez de 403Falta require_org fenceCommon gatesrequire_org(request) (reemplaza get_current_org, levanta 403 limpio)
sa4 A2Fuga de secretos: NotificationChannelOut exponía config íntegra (webhook URLs, tokens, API keys)List/create/update sin enmascararitsm.py + notification_service.pyredact_channel_config() en responses; merge_preserving_secrets() en PUT (evita que un roundtrip borre el secreto)
sa4 A5Inyección de comandos en runbooks: validate_commands se saltaba lineas con \nValidación incompletacommand_validation.pyRechaza \n \r ; | & \x00 antes de allowlist
sa5 A10snmp_community en body REST de deep-discoverMitigado por require_perm (readonly ya no alcanza el endpoint)wireless.py, ups.pyGeen eliminación (fallback REST relaya WS no autenticado); fix profundo = PR aparte

Hallazgos MEDIO corregidos

IDHallazgoFix
sa4 M2test_channel devuelve HTTP 200 aunque falleAhora devuelve 400/502 según error real (Regla 15: 200 ≠ éxito)
sa4 M3, M6, B9; sa5 B3, B10Falta audit log en mutaciones ITSM/alertsDiferido a PR aparte con decorador centralizado
sa4 M9; sa5 M4AlertIn + SentinelModeIn + ThresholdUpdateIn sin validaciónValida condition_type/severity contra enum, intervalos (5..86400 s), retención (1..365 d), threshold (no NaN/inf)
sa4 M10Tormenta de AlertEvent: N eventos/ciclo para una condición persistenteReutiliza evento abierto (resolved_at IS NULL); solo crea uno nuevo tras resolver
sa4 M12Supresión por mantenimiento ignorada en escalados (escalated_l* events)Supresión ahora aplica a todos los eventos y solo si ventana activa (start ≤ now ≤ end)
sa4 M13resolution_rate contaba acknowledged como resueltoAhora cuenta resolved_at IS NOT NULL (coherente con get_sla_metrics)

Cambios por archivo

monitoring/api/alerts.py

monitoring/api/itsm.py

monitoring/api/itsm_groups.py

monitoring/api/itsm_knowledge.py

monitoring/api/itsm_reports.py

monitoring/api/itsm_runbooks.py


Servicios internos reforzados

monitoring/services/notification_service.py

monitoring/services/alert_service.py

monitoring/services/sla_service.py

monitoring/services/deep_discover_service.py (nuevo)


Validación de inputs

Nuevas restricciones en schemas (Ninja):

SchemaValidación
AlertIncondition_type en ["cpu", "memory", ..., "custom"]; severity en ["low", "medium", "high", "critical"]
SentinelModeIninterval y check_interval en rango [5 s, 86400 s]; retention_days en [1, 365]
ThresholdUpdateInthreshold_value rechaza NaN, inf, valores inválidos
Sink _query_range (wireless/ups)_clamp_hours(hours) acota a [1 min, 180 d]

Tests

Nuevo archivo: tests/api/test_monitoring_sa4_sa5.py

Suite total


Resumen de impacto

MétricaValor
Handlers reforzados con autorización89
Secretos enmascarados en responses5 hallazgos + N endpoints
Hallazgos ALTA cerrados18
Hallazgos MEDIO cerrados~10
Tests nuevos22
Cambios DB0 (no migraciones)
Riesgo de breaking changesBajo (solo 403 para readonly en mutaciones; compatible con RBAC existente)

Decidido como trabajo futuro (PRs separadas)

  1. Cifrado en reposo de NotificationChannel.config (sa4 A2 2ª mitad)

    • Requiere smoke test STAGE (toca envío de notificaciones).
    • PR dedicado con crypto key rotation.
  2. Audit logs en mutaciones (sa4 M3/M6/B9 · sa5 B3/B10)

    • PR con decorador centralizado.
    • Evita volver a romper el límite de 500 LOC en itsm.py.
  3. Fix profundo de deep-discovery sin SNMP en body (sa5 A10)

    • Cambia protocolo Local Agent (job_id + pull autenticado).
    • Diferido porque requiere coordinación con infraestructura.
  4. Backlog BAJA: paginación, N+1 menores, audit symmetry.

    • Documentado en monitoring-sa{4,5}.md.

Véase también

Subir