--- type: OUT asset_id: OUT-EL-IntelliBanks-WargameConfidencialidad-Huecos-v01 version: v01 status: Salida de wargame · ejecutado por Opus (equipo rojo) 2026-07-12 · pendiente ratificación Victor (L3) owner: Victor Heredia sherpa: Jay ratificador: Victor Heredia (L3+) superficie: LAB fecha_creacion: 2026-07-12 intellbank: IB-EL-EmpowerLabs subbank: PB-EL-Project-Bank/PB-EL-IALab/WG-EL-WarRoom/Wargames experimento: EXP-2026-13 ejecutado_por: Opus 4.8 (equipo rojo · juez adversarial) proposito: > Salida del wargame de seguridad del ARQ de Confidencialidad + Control de Acceso de IntelliBanks. Tabla de huecos priorizada, unknown-unknowns no marcados por el diseñador, y veredicto de arranque. Vuelve al ARQ como correcciones antes de Fase 1b. insumos: - WG-EL-IntelliBanks-ConfidencialidadAcceso-v01 (semilla · 6 vectores) - ARQ-EL-IntelliBanks-ConfidencialidadAcceso-v01 (diseño atacado) - ARQ-EL-IntelliBanks-MultiEmpresa-ZeroTrust-v01 (EXP-09 · base) tags: [OUT, wargame, intellibanks, confidencialidad, seguridad, red-team, opus, huecos, LAB, EXP-2026-13] --- # SALIDA DE WARGAME — Confidencialidad + Control de Acceso IntelliBanks ## Equipo rojo: Opus · 6 vectores jugados · veredicto: CONSTRUIR CON CONDICIONES (con una capa a re-diseñar) > **Marco.** Fable diseñó, Opus atacó. No auto-aprobé nada. El núcleo de control de acceso contra un **no-autorizado** resiste (con una condición de auditoría). Pero la garantía que el diseño más vende — *"exfiltración atribuible"* para C2 — **se rompe como está escrita**: el watermark no protege el canal por donde el contenido realmente llega al cliente. Ese es el hallazgo central. Abajo, cada vector con su veredicto, luego los huecos priorizados, los unknown-unknowns, y la decisión de arranque. --- ## 1. Resultado por vector | Move | Vector | Veredicto | Nota corta | |---|---|---|---| | 1 | No-autorizado que entra | 🟢 **Victoria azul, condicional** | El core Zero-Trust aguanta; cae 🟡 por endpoints legacy sin auditar y por fuga de *existencia* vía rutas. | | 2 | Exfiltrador autorizado (C2) | 🔴 **HUECO CRÍTICO** | El watermark es un overlay; el texto limpio llega al cliente en el DOM/buffer. Atribución no garantizada. | | 3 | Suplantación (token/ticket/CDN) | 🟡 **Hueco medio-alto** | CDN OK; el "ticket atado a dispositivo" es aspiracional — sin binding de hardware, ticket robado = token robado. | | 4 | Bypass de consulta-in-place | 🔴 **HUECO ALTO** | El cache de render base es un repositorio de copias LIMPIAS server-side; + depende de 3 supuestos abiertos. | | 5 | Escalada de clase / privilegio | 🟠 **Hueco alto (gobernanza)** | Cobertura de reglas por ruta + grants a ROL diluyen la doble firma. Talón de Aquiles humano. | | 6 | Caos a escala / kill-switch | 🟠 **Hueco medio + 1 crítico oculto** | Ventana de 5 min discutible; y el heartbeat **fail-open offline** es un bypass total no marcado. | **Traducción:** el sistema distingue bien *quién puede pedir*, pero es débil en *qué pasa con el contenido una vez entregado a alguien que sí podía pedirlo* — y ahí es donde vive la promesa de C2. --- ## 2. El hallazgo central (ata MOVE 2 + MOVE 4) **El watermark protege los píxeles; el contenido no siempre viaja como píxeles.** El ARQ §3.3 entrega el render como **HTML sanitizado** para `.md/.html` (el grueso del vault) y como PDF/imagen solo para PDF. El watermark §3.4 se describe "estampado server-side". Pero para un render HTML, el watermark visible es un **overlay CSS** y el forense son "micro-variaciones de espaciado": en ambos casos, **los nodos de texto del DOM contienen el contenido limpio, sin marca**. Un viewer instrumentado (o devtools, o un cliente recompilado — R-2/R-3, que el diseño ya admite como posibles) lee `document.body.innerText` y obtiene el texto **limpio y no atribuible**. El watermark nunca tocó el texto; solo la capa visual encima. Y peor, MOVE 4 lo confirma desde el otro lado: el ARQ cachea "el render por versión del doc" server-side. Como el watermark es **por-usuario** y el cache es **por-doc**, el cache necesariamente guarda la versión **base sin marca**, aplicando el watermark después. Es decir: **existe, server-side, un repositorio de renders limpios**. Cualquier ruta que sirva ese cache directamente (traversal, endpoint de conversión, bug de clearance en la lectura de cache) es una fuga de copia limpia — no atribuible. **Conclusión dura:** la garantía "exfiltración atribuible" de C2 **solo puede sostenerse si el render que llega al cliente es rasterizado (píxeles) con el watermark por-usuario horneado en esos píxeles, sin que exista en el cliente ningún buffer de texto pre-watermark, y sin que el cache base sea servible.** Como está diseñado (HTML con overlay + cache base por-doc), C2 no cumple lo que promete. Esto **no es un ajuste de parámetro: es re-diseñar el canal de render para C2.** --- ## 3. Tabla de huecos priorizada ### 🔴 CRÍTICOS (bloquean prometer C2; resolver antes de construir C2) | # | Hueco | Vector | Contramove propuesto | Owner | |---|---|---|---|---| | H-1 | **Texto limpio en el DOM.** El watermark HTML es overlay; el contenido C2 llega limpio al cliente y es leíble/exfiltrable sin marca ni atribución. | 2 | Para C2, render **rasterizado server-side** (páginas como imágenes con watermark por-usuario horneado; nunca HTML con texto vivo). Desactivar selección/DOM de texto. Evaluar visor de imágenes puro. | Alex (factibilidad) + Victor (acepta el costo UX: C2 no seleccionable, más pesado) | | H-2 | **Cache de render base = copias limpias.** El cache por (doc+versión) guarda el render sin watermark; es un almacén de copias limpias server-side. | 4 | Cache de la **versión base** en zona no servible directamente; el watermark por-usuario se hornea en el punto de entrega, no cacheado; toda lectura del render pasa por clearance ANTES de tocar cache; clave de entrega = (doc+versión+usuario) o no-cache para C2. | Alex | | H-3 | **Watermark forense no especificado ni probado (V6).** Toda la atribución de C2 descansa en una capacidad que el ARQ asume, no diseña. Marcas espaciales no sobreviven recorte; texto retecleado la elimina. | 2 | Definir algoritmo real, unicidad por-vista e irreversibilidad, y **probar** resistencia a screenshot+recorte+recompresión ANTES de prometer C2. Si no hay watermark robusto → reclasificar R-1/R-2 a "no prevenible" y C2 exige control fuera de software (visor en entorno controlado) o se elimina. | Victor (decisión) + Alex | ### 🟠 ALTOS (resolver antes de Fase 1b / Fase 2 según toque) | # | Hueco | Vector | Contramove propuesto | Owner | |---|---|---|---|---| | H-4 | **Heartbeat fail-open offline.** Si el viewer, al perder red, no cae en fail-closed, un usuario abre un C2, se desconecta (modo avión) y lo ve **indefinidamente** sin posibilidad de revocación. Kill-switch anulado. **No marcado por el diseñador.** | 6 | El viewer C2 **fail-closed**: sin heartbeat exitoso en N segundos → se cierra solo. Sin red = sin C2. Documentar como comportamiento, no como bug. | Alex + Victor (N segundos) | | H-5 | **Cobertura de reglas de clase por ruta.** La confidencialidad solo protege lo que cae bajo un `path_prefix` declarado; un doc sensible en carpeta sin regla nace C0 y sincroniza en claro. Mismo talón del naming en EXP-09. | 5 | Default-deny por sensibilidad en zonas de riesgo (ej. `IB-Clientes/*` nace C1 salvo excepción explícita) y/o clasificador que marque candidatos para revisión. La clasificación es tan buena como su cobertura. | Victor (política) + equipo WORX | | H-6 | **Grants a ROL diluyen la doble firma.** `doc_grants` admite `principal_type='role'`; un grant a rol 'member' expone el doc a TODOS los miembros, y agregar un usuario a un rol privilegiado esquiva el escrutinio por-doc de C2. | 5 | C2 **solo admite grants nominales** (`principal_type='user'`), nunca a rol. Cambios de membresía de rol con clearance C2 = evento auditado y ratificado. `granted_by <> ratified_by` enforced por esquema (CHECK), no por convención. | Alex + Victor | | H-7 | **"Ticket atado a dispositivo" es aspiracional.** Sin binding de hardware, el ticket se ata al token; token robado (archivo `.user_session.json` de máquina desbloqueada) = ticket válido desde la máquina del atacante. El criterio g-5 no se cumple como está. | 3 | Para abrir C2: **re-autenticación paso-arriba** (segundo factor / re-login) aunque el token esté vivo — el token da acceso al OS, no automáticamente a C2. Alternativa: expiración corta de token. | Victor (fricción vs seguridad) + Alex | ### 🟡 MEDIOS (cerrar en construcción; varios son confirmar-supuesto) | # | Hueco | Vector | Contramove / acción | Owner | |---|---|---|---|---| | H-8 | **Endpoints legacy sin gate.** El core de MOVE 1 asume que TODOS los endpoints pasan por `gate.php`. Un endpoint heredado de EXP-09 sirviendo por `usuario` legacy es fuga directa. | 1 | Inventario exhaustivo de endpoints + prueba de que cada uno incluye gate; **deny-by-default a nivel router** (whitelist de endpoints migrados) en vez de confiar en que cada endpoint llame gate. | Alex | | H-9 | **Fuga de existencia por ruta.** Aunque el contenido C2 no se sirva, la existencia de la ruta (`IB-Clientes/Acme/Legal/Despido-CEO.md`) puede filtrarse por listados de carpeta o metadatos; y descubrir-para-pedir-grant queda sin resolver. | 1 | Definir política: los segmentos de ruta de docs C2 no aparecen para quien no tiene grant; canal separado y auditado para solicitar acceso a algo que no puedes ver. | Victor + Alex | | H-10 | **Consulta-in-place depende de V2/V3/V4 (Electron + previewer).** Partición en-memoria, cancelación de `will-download` y temporales del previewer son supuestos abiertos; si alguno falla, el "cero aterrizaje" se cae. | 4 | Confirmar con código a la vista antes de Fase 2. Si Electron no da partición limpia → fork a visor server-side puro (stream de imágenes). | Alex | | H-11 | **Ventana de kill-switch de 5 min** sobre vistas C2 ya abiertas. Para un corte de seguridad urgente puede ser demasiado. | 6 | Para C2 abierto: heartbeat corto (ej. 15s) **o** invalidación push (el servidor cierra el viewer activamente, no espera el heartbeat). | Victor (TTL) + Alex | | H-12 | **Carrera clase-vs-cache.** Subir un doc a C2 mientras un cache/sync aún lo tiene como C0 = ventana de fuga por el canal viejo. | 6 | Subir clase **invalida cache y saca del sync map ANTES** de confirmar la operación; orden de retiro local se dispara en la misma transacción. | Alex | --- ## 4. Unknown-unknowns (no marcados por el diseñador) 1. **U-1 · Fail-open offline del heartbeat (H-4).** El diseño trató el heartbeat como mecanismo de revocación, pero nunca definió qué pasa **sin red**. Modo avión convierte el kill-switch de "≤5 min" en "nunca". Es el hueco más silencioso y el más grave de los operativos: no requiere hackear nada, solo desconectar el wifi con un C2 abierto. 2. **U-2 · El cache base como almacén de copias limpias (H-2).** El diseñador presentó el cache de render como optimización de rendimiento; adversarialmente es un **repositorio de versiones sin watermark** que contradice la premisa "solo existe la versión marcada, no hay endpoint que sirva la limpia" (ARQ §3.4). La optimización creó, sin querer, exactamente el artefacto que el diseño juraba no tener. 3. **U-3 · C1 protege menos de lo que aparenta.** C1 permite `edit: in-place` y `copy_text: true`; para editar, el texto completo vive en un buffer editable en el cliente. C1 no es "contenido protegido" — es "contenido sin archivo local". Un usuario C1 tiene, funcionalmente, el texto completo copiable. Está dentro de la política declarada, pero el nombre "Restringido" sobre-vende la protección: la única clase con protección real de exfiltración es C2 (que es justo la que falla en H-1). Implicación: hoy no hay ninguna clase que entregue exfiltración-resistente de verdad hasta cerrar H-1/H-3. --- ## 5. Veredicto de arranque **CONSTRUIR CON CONDICIONES — con una capa (canal de render C2) a RE-DISEÑAR antes de prometer C2.** Desglose por clase, porque el veredicto no es uniforme: - **Control de acceso + C0/C1 → construir con condiciones.** El núcleo (identidad EXP-09, deny-by-default, gating por-request, no-aterrizaje para C1) es sólido. Condiciones: cerrar H-8 (auditoría de endpoints), H-10 (confirmar Electron/previewer), H-5/H-6 (cobertura de clasificación y grants a rol). Entra con Fase 1b/2 de EXP-09 como estaba planeado. - **C2 (sellado) → re-diseñar el canal de render antes de prometerlo.** H-1 + H-2 + H-3 significan que C2, como está, **no entrega la atribución que promete**. No se debe ofrecer C2 a un cliente hasta: (a) render rasterizado con watermark horneado por-usuario, (b) cache base no servible, (c) watermark forense especificado y probado — o, si (c) no es alcanzable, reclasificar el riesgo y mover C2 a un control fuera de software. **Decisión de Victor (L3).** - **H-4 (fail-open offline) → arreglar sí o sí, cualquier clase confidencial.** Es barato y anula el kill-switch. No debería sobrevivir a la primera revisión. **Ninguna condición de aborto total se disparó:** un no-autorizado no recibe bytes (MOVE 1 aguanta con H-8 cerrado), así que el sistema no vuelve al pizarrón completo. Pero la clase C2 sí toca su condición de aborto específica del WG- (§4: "watermark no robusto Y Victor no acepta reclasificar → C2 se re-diseña"). Se re-diseña la capa, no el sistema. --- ## 6. NEXTs - [ ] **Victor (L3)** — ratificar esta salida y decidir los tres dilemas de negocio: (1) C2 rasterizado no-seleccionable (acepta el costo UX) vs C2 fuera de software; (2) paso-arriba de auth para abrir C2 (H-7); (3) default-deny por sensibilidad en `IB-Clientes/*` (H-5). - [ ] **Alex** — confirmar V2/V3/V4 con código a la vista (H-10) y factibilidad de H-1/H-2 (render rasterizado + cache base no servible) y H-4 (fail-closed offline). - [ ] **Fable / room de diseño** — recalibrar `ARQ-EL-IntelliBanks-ConfidencialidadAcceso-v01` a v01-r1 incorporando H-1..H-12 (especialmente re-diseño del canal de render C2 §3.3–3.4). - [ ] **Jay** — registrar CAS en el LabPraxis: "el watermark protege píxeles, no el canal — el cache de optimización recreó la copia limpia que el diseño juraba no tener" (patrón reusable para futuros diseños de DRM/confidencialidad). - [ ] Tras recalibración + ratificación → handoff a Alex/Codex para Fase 1b (acceso + C0/C1); C2 espera su re-diseño. --- ## CHANGELOG | Versión | Fecha | Cambio | |---|---|---| | v01 | 2026-07-12 | Ejecución del wargame por Opus (equipo rojo) sobre el ARQ de confidencialidad. 6 vectores jugados; 12 huecos priorizados (3 críticos, 4 altos, 5 medios) + 3 unknown-unknowns no marcados por el diseñador. Hallazgo central: el watermark protege píxeles pero el render HTML entrega texto limpio en el DOM y el cache base almacena renders sin marca — C2 no entrega la "exfiltración atribuible" que promete. Veredicto: CONSTRUIR CON CONDICIONES (acceso + C0/C1) con el canal de render C2 a RE-DISEÑAR. H-4 (heartbeat fail-open offline) elevado como bypass total del kill-switch. Pendiente ratificación Victor. |