Cero JS en cliente = Cero XSS
Oasis rechazó JS en el cliente. Consecuencia de seguridad positiva: sin JS no hay XSS posible — no hay runtime que un atacante pueda secuestrar. El vector de ataque restante es CSRF.
Defensa CSRF en profundidad
Un sitio malicioso en otra pestaña podría enviar un <form> POST a localhost:3000/webrtc/*. Tres capas complementarias lo impiden:
| Capa | Mecanismo | Bloquea en |
| Referer check |
Middleware Koa rechaza POST cuyo Referer no sea localhost:PORT |
Servidor |
| SameSite=Strict |
Cookie de sesión no se envía en requests cross-origin |
Navegador |
| CSP form-action 'self' |
Los formularios solo pueden POST a 'self' |
DOM |
Las tres capas son complementarias. Un atacante necesitaría saltarse las tres simultáneamente.
Estrategia CSP dual
Ruta LAN (browser local SNH): script-src 'none' — bloqueo total de JS.
Ruta remota (si HLS requiere hls.js en Firefox desktop): CSP separada con script-src 'self' en ruta /remote específica.
Principio: la ruta más restrictiva (script-src 'none') es la default. Solo se relaja en rutas concretas que lo justifiquen, y solo para JS propio.
Headers de seguridad recomendados
Content-Security-Policy: default-src 'self'; script-src 'none'; img-src 'self'; media-src 'self'; form-action 'self'; frame-ancestors 'none'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: same-origin
WebRTC ↔ Tor: tensión fundamental
El SNH enruta tráfico por Tor + Privoxy. WebRTC necesita la IP real del peer para ICE. Esto crea un conflicto directo:
Tor oculta tu IP ←──── CONFLICTO ────→ WebRTC revela tu IP
(privacidad) (para ICE candidates)
| Escenario | IP expuesta | Privacidad | WebRTC |
| LAN sin Tor (Fase 1–2) |
IP local (192.168.x.x) |
N/A (red local) |
✅ Plena |
| Internet + STUN |
IP pública real |
❌ IP revelada |
✅ Funciona |
| Internet + TURN |
IP del servidor TURN |
⚠️ Parcial |
✅ Funciona |
| Todo por Tor |
IP del exit node |
✅ Máxima |
❌ ICE falla (no UDP) |
| TURN sobre Tor |
IP del exit node |
⚠️ TURN conoce exit |
⚠️ Latencia 500ms+ |
Recomendación por fase
| Fase | Estrategia | Notas |
| Fase 1–2 (LAN) |
Tor no interviene. WebRTC funciona con candidatos host directamente. |
Sin conflicto |
| Fase 3 (Internet) — Pragmática |
TURN propio del pub SSB. Deshabilitar candidatos srflx. |
iceTransportPolicy: 'relay' |
| Fase 3 — Máxima privacidad |
No usar WebRTC para media. Audio por Mumble/TCP sobre Tor hidden service. Vídeo por go2rtc/HLS sobre HTTP. Datos por DataChannel sobre TURN/TCP. |
→ Arq. 3 |
Mumble tuneliza audio por TCP nativo, que funciona directamente sobre Tor como hidden service. Sin TURN, sin STUN, sin ICE. Simplicidad radical.
Nota Firefox SNH
Firefox del SNH tiene media.peerconnection.ice.default_address_only = true por defecto, lo que limita los candidatos ICE a una sola interfaz. Mitiga parcialmente la filtración de IPs múltiples pero no el conflicto fundamental con Tor.