Descripción
Cierre del barrido de seguridad de toda la interfaz legacy (static/js, 7 sub-áreas). La raíz R2 del Informe Supremo era escape inconsistente: existía window.escapeHtml pero no se aplicaba en todos los renders, y era insuficiente en contexto de atributo (no escapaba comillas) y URL (no bloqueaba javascript:).
Este commit crea 4 helpers de escape por contexto reutilizables y los aplica sistemáticamente en 41 ficheros de todo el frontend:
escapeHtml(s)— contexto texto/contenido de elemento (escapa<,>,&).escapeAttr(s)— valores dentro de atributos entrecomillados (title, data-*, value, style). Escapa también comillas → no se puede romper el atributo.safeUrl(s)— devuelve#si la URL usa esquemajavascript:,data:ovbscript:. Para href/src construidos con datos no confiables.sanitizeCsvCell(s)— antepone'a un=,+,-,@inicial → neutraliza CSV/formula injection en exportes.
Áreas corregidas
| Sub-área | Ficheros | Hallazgos principales |
|---|---|---|
| FE7 (core) | base.js, QRLabelService, ChartCreators | ALTA: nombres de rack/location en innerHTML, sysName/hostname SNMP en tooltip heatmap |
| FE2 (editor) | DeviceInfoModal, PropertiesPanel, backups, sftp_ui | ALTA: datos SNMP (kvRow), filenames SNMP (sftp), nombres/notas de device en inputs |
| FE4 (network/discovery) | Discovery, HealthCheck, PortScanner, TargetManager, RangeManager | ALTA: tabla de resultados, modal viewProfile, vendor/hostname/MAC crudos, href con safeUrl |
| FE5 (observatory/wireless/ups) | ObservatoryDeviceList, Tabs, Alerts, WirelessReport, UpsReport | ALTA: nombres/IP de device/target, breakout de atributo data-*, CSV injection en exportes, error.message en heatmap |
| FE6 (signage) | SignageContentGrid, PlaylistManager, ClientManager, ScheduleRenderers, Detail | ALTA: 19 hallazgos — nombres del CMS (asset/playlist/project/device) en grids/modales/schedule, CSV injection, bg_color en atributo style |
Verificación
static/js/no entra en CI (biome solo cubrefrontend/src) → verificado connode --checken 41 ficheros + revisión del diff (sin doble-escape, sin escapar literales HTML de confianza, sin tocar credenciales/storage).- R3 (credenciales en cliente) NO se toca: SSH/SNMP/SpinetiX en localStorage/WS son cambio de contrato con
.exedel Agent, diferidos a iniciativa propia. - Diferidos: bug undo/redo
createDrawingNode(FE3), BAJA cosméticas/perf/dead-code, SVG preview del backend en playlists.
Impacto en el producto
Antes: Un nombre de equipo o contenido manipulado podía ejecutar código JavaScript en el navegador de quien lo vea (XSS), y un CSV exportado podía ocultar fórmulas peligrosas que Excel/LibreOffice ejecuta automáticamente.
Después: La interfaz ya blinda todos los nombres de equipos, datos SNMP, contenidos del CMS frente a “trampas” ocultas. El nombre de un dispositivo descubierto en la red o de una pantalla de signage ya no puede ejecutar código, y los exportes CSV ya no pueden colar fórmulas.
Línea de tiempo
- 2026-06-05: Inicio Auditoría Suprema (monitoring SA1-SA5, network SA1-SA5).
- 2026-06-09: FE3 (blueprints) + FE1 (terminal) + FE7 cimientos + Plan Hardening cerrado.
- 2026-06-11: FE1 + FE7 (helpers) + commit base #112.
- 2026-06-12: Aplicación FE2-FE6 + cierre Etapa 3 (commit 6304eb5, sesión 130).
Sesión de desarrollo
s130 (2026-06-12 · Sesión 130 · Auditoría Suprema Etapa 3 · barrido XSS/CSV FE2-FE7)
Autor: Edu (con Claude Code)
Commit: 6304eb5a64b95641c40ef6770e694735ff7e61a2
Véase también
- [[entity—frontend—service—escape-helpers]]
- [[concept—seguridad—xss]]
- [[concept—seguridad—csv-injection]]
- [[concept—producto—frontend-legacy]]
- [[decision—20260605—auditoria-suprema-metodologia]]