14 KiB
Feature Specification: Cibersegurança do Wizard — Telemetria em Tempo Real (021)
Criado: 2026-06-17
Solicitado por: Roger
Status: Spec — implementação pendente
Prioridade: P1
Sistema: Wizard VM112 (/opt/ligbox-wizard) + Portal onboard + Desk VM122
Módulo Desk: wizard-security (novo — Spec 015)
Depende de: Spec 001/014 (webhooks + funil), Spec 015 (módulos), Spec 016 (handoff + sessionStorage)
UI principal: Audit Overview → tenant VM112 + Infra 2 + Eventos
Resumo
Estender a observabilidade do onboarding com vias de cibersegurança dos processos do wizard: CSP (browser), auditoria de inputs (API VM112), integridade do handoff server-side e eventos de abuso — tudo visível em tempo quase real no Desk VM122, na mesma sessão (session_id / hash) do funil.
Princípio: isto é camada extra de detecção e resposta — complementa (não substitui) HTTPS, handoff one-time, React escaping e ausência de SQL no fluxo de credenciais.
Regra de ouro: nunca enviar senhas, tokens de handoff completos nem corpos de request com PII sensível nos webhooks de segurança.
Problema
| Hoje | Necessidade |
|---|---|
Desk vê progresso do funil (session.started → completed) |
Ver também tentativas de abuso na mesma sessão |
| Audit Overview = saúde infra (Carbonio, DNS, cert) | Card Segurança onboarding por tenant VM112 |
| CSP / validação de inputs inexistentes ou invisíveis | Política activa + relatórios no Desk |
| IA/fuzzing acelera ataques | Alertas operacionais sem esperar abuse report |
Modelo de ameaças (wizard VM112)
| Ameaça | Camada actual | Gap | Via Spec 021 |
|---|---|---|---|
| XSS (ler sessionStorage) | React escape + sem dangerouslySetInnerHTML |
Sem CSP nem reporte | CSP + security.csp_violation |
| SQL injection | Handoff sem SQL (JSON encriptado) | Outras APIs futuras | Middleware security.input_blocked |
| Roubo handoff token | Token opaco, TTL 15 min, one-shot | Sem telemetria de reutilização | security.handoff_rejected |
| Senha na URL | Nunca — só ?onboard_handoff= |
— | Auditoria confirma ausência |
| MITM | HTTPS Let's Encrypt | — | Fora de escopo (já coberto) |
| Fuzzing / brute | Parcial | Sem rate limit visível | security.rate_limited |
| Path traversal / SSRF | Não auditado | — | security.input_blocked |
| IA a gerar payloads | Mesmas defesas | Sem feed SOC | Eventos no Desk em segundos |
O que sessionStorage não é
- Não protege contra SQL injection (corre só no browser).
- Risco real: XSS bem-sucedido → script lê
ligbox_onboard_password. - Resposta Spec 021: CSP reduz superfície + reporta violações; inputs maliciosos bloqueados antes de chegar ao estado.
Vias de processo — mapa completo
Via 1 — Credenciais (Portal → Wizard)
Utilizador (onboard.ligbox.com.br)
→ Self-Service / Login (HTTPS)
→ POST /onboard-handoff [VM112 API — senha encriptada server-side]
→ redirect ?onboard_handoff=<token_opaco>
→ POST /consume [one-shot, apaga token]
→ sessionStorage.ligbox_onboard_password [temporário, mesma origem]
→ wizard /onboard
Eventos de segurança:
| Evento | Quando |
|---|---|
security.handoff_created |
Handoff emitido (sem senha no payload) |
security.handoff_consumed |
Consume OK |
security.handoff_rejected |
Token expirado, reutilizado, session mismatch |
security.handoff_expired |
TTL 15 min excedido |
Via 2 — Inputs do wizard (passos 0–N)
Rotas VM112 a auditar (mínimo):
| Endpoint / acção | Campos |
|---|---|
| Validação domínio | domain, FQDN |
| Conta admin | localPart, domain, email |
| DNS / Cloudflare | domain, records |
| Portal users | login_id, planned_corporate_email |
| Company profile | legal_name, tax_id, texto livre |
| Handoff consume | token, session_id |
Eventos:
| Evento | Severidade | Acção API |
|---|---|---|
security.input_warn |
baixa | Sanitizar + log + webhook |
security.input_blocked |
alta | HTTP 400 + log + webhook |
security.rate_limited |
média | HTTP 429 + webhook |
Padrões detectados (regex/heurística MVP):
- SQLi:
' OR,UNION SELECT,; DROP,1=1-- - XSS:
<script,javascript:,onerror=,onload= - Path:
../,%2e%2e - Command:
`,$(,|,&& - Oversize: campo > limite (ex. domínio > 253, nome > 500)
Nunca logar: password, root_password, corpo de /consume com segredos.
Via 3 — CSP (browser → Desk)
Browser (portal + wizard)
→ viola Content-Security-Policy
→ POST report-uri / report-to
→ VM122 /api/v1/security/csp-report
→ webhook_events (source: vm112-security)
→ Audit Overview + Infra 2 + Eventos
Header CSP (Traefik / nginx — portal + wizard):
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://desk.ligbox.com.br;
frame-ancestors 'none';
base-uri 'self';
report-uri https://desk.ligbox.com.br/api/v1/security/csp-report;
(Ajustar connect-src para APIs VM112/Traefik em produção.)
Evento: security.csp_violation — inclui blocked-uri, violated-directive, document-uri (sem dados de utilizador).
Via 4 — Correlação com funil (VM122)
Cada evento security.* deve incluir quando disponível:
session_id(hash UUID)domainclient_ip(ingress)endpoint/wizard_stepseverity:info|warn|high|critical
O Desk correlaciona com timeline Spec 014 na mesma sessão.
Módulo Desk (Spec 015)
| Campo | Valor |
|---|---|
id |
wizard-security |
label |
Segurança Wizard |
default_enabled |
true |
nav_views |
(enrichment — Audit Overview, Infra 2, Eventos) |
Desactivar módulo → APIs devolvem payload sem security_summary; UI oculta card e filtro.
RBAC
| Acção | Perfis |
|---|---|
| Ver card Segurança no Audit Overview | super_admin, ops_lead |
| Ver feed segurança Infra 2 | super_admin, ops_lead, noc |
Ver eventos security.* em Eventos |
super_admin, ops_lead, noc |
POST csp-report |
Público (browser) — rate limit + validação schema |
| POST webhook segurança VM112 | X-Webhook-Secret (mesmo ou derivado de onboard) |
Técnicos technician — sem card segurança (opcional: só tickets ligados).
API Desk (VM122)
Ingestão
| Método | Path | Auth | Descrição |
|---|---|---|---|
| POST | /api/v1/security/csp-report |
nenhum (browser) | Relatório CSP (JSON W3C ou legacy) |
| POST | /api/v1/webhooks/security |
X-Webhook-Secret |
Eventos VM112 security.* |
| POST | /api/v1/webhooks/onboard |
existente | Aceitar também security.* no mesmo ingress (opcional) |
Consulta
| Método | Path | Descrição |
|---|---|---|
| GET | /api/v1/security/events?window=24h&session_id= |
Lista eventos segurança |
| GET | /api/v1/security/summary?tenant_id=1 |
KPIs para Audit Overview |
| GET | /api/v1/audit/tenants/1/details |
Enriquecido com security_summary + security_events_recent |
Payload webhook (VM112 → VM122)
{
"event": "security.input_blocked",
"session_id": "ee2239fd-dd05-444e-b79c-a5701a255ba8",
"domain": "evil.example",
"data": {
"endpoint": "POST /api/domains/validate",
"field": "domain",
"reason": "sql_injection_pattern",
"pattern_id": "sqli_union",
"client_ip": "203.0.113.42",
"wizard_step": 0,
"severity": "high"
}
}
Proibido no payload: passwords, tokens handoff completos, headers Authorization.
Persistência
Tabela nova ou reutilizar webhook_events:
| Opção | Prós |
|---|---|
A — webhook_events com source=vm112-security |
Reutiliza Eventos, Infra 2, funil |
B — tabela security_events dedicada |
Queries mais rápidas, retenção própria |
MVP: opção A (consistente com arquitectura actual).
Índices recomendados: (source, created_at), (session_id), (event_type).
API VM112 (wizard)
Middleware security_audit.py (novo)
- Executar antes do handler em rotas listadas na Via 2.
- Retornar 400/429 com corpo genérico (não revelar qual regex matched em produção — opcional
reasoninterno no webhook only). - Fire-and-forget POST para VM122 (não bloquear UX se Desk offline).
Cliente webhook
Reutilizar cliente existente de onboarding (session.started, etc.) com fila retry (3 tentativas, backoff 2s).
Config (.env VM112)
DESK_SECURITY_WEBHOOK_URL=https://desk.ligbox.com.br/api/v1/webhooks/security
DESK_WEBHOOK_SECRET=<mesmo WEBHOOK_SECRET>
SECURITY_AUDIT_ENABLED=true
SECURITY_RATE_LIMIT_PER_IP=60/min
UI Desk
Audit Overview → modal VM112 Ligbox Onboard
Novo bloco «Segurança onboarding» (acima ou abaixo do resumo domínios):
| KPI | Exemplo |
|---|---|
| Violações CSP (24h) | 3 |
| Inputs bloqueados | 1 |
| Handoffs rejeitados | 0 |
| Sessões com alerta | 2 |
Lista recente (clicável → detalhe):
| Hora | Sessão (hash) | Evento | IP | Domínio |
|---|---|---|---|---|
| 21:42 | ee2239fd… |
security.csp_violation |
203.0.113.1 | — |
| 21:40 | 3dfa8c6c… |
security.input_blocked |
198.51.100.5 | foo';DROP-- |
Clique → modal com timeline funil + segurança intercalados (ou abas).
Infra 2 (SOC)
- Painel «Segurança wizard» no feed (15s refresh).
- Flash visual em
security.input_blockedesecurity.csp_violation(como eventos novos no feed VM112).
Eventos
- Filtro toolbar: Segurança (
source=vm112-securityoueventprefixsecurity.). - Colunas: severidade, evento, sessão (hash completo), domínio, IP, hora.
Tickets (opcional Fase C)
Auto-ticket quando:
- ≥3
security.input_blockedmesmo IP em 10 min, ou security.csp_violation+security.input_blockedmesma sessão
Subject: [security] {domain|sem domínio} — {event} · prioridade alta.
Taxonomia de eventos security.*
| event | Label UI | Severidade default |
|---|---|---|
security.csp_violation |
Violação CSP | warn |
security.input_warn |
Input suspeito (sanitizado) | info |
security.input_blocked |
Input bloqueado | high |
security.rate_limited |
Rate limit | warn |
security.handoff_created |
Handoff criado | info |
security.handoff_consumed |
Handoff consumido | info |
security.handoff_rejected |
Handoff rejeitado | high |
security.handoff_expired |
Handoff expirado | info |
security.auth_failed |
Autenticação portal falhou (agregado) | warn |
security.session_anomaly |
Sessão inconsistente (IDs mismatch) | high |
Fases de implementação
Fase A — Ingestão VM122 (Desk)
- T001
POST /api/v1/security/csp-report+ validação schema + rate limit - T002
POST /api/v1/webhooks/security(ou extensão onboard ingress) - T003 Persistência
webhook_eventssourcevm112-security - T004
GET /api/v1/security/summarye/security/events - T005 Registar módulo
wizard-securityemregistry.py
Fase B — VM112 wizard
- T006 Middleware auditoria inputs (Via 2)
- T007 Eventos handoff (Via 1)
- T008 Cliente webhook segurança + retry
- T009 Testes unitários padrões SQLi/XSS
Fase C — UI Desk
- T010 Card Segurança no Audit Overview modal VM112
- T011 Filtro Eventos «Segurança»
- T012 Painel Infra 2 + flash eventos novos
- T013 Hash sessão na lista (já feito — correlacionar)
Fase D — Infra Traefik/nginx
- T014 CSP headers portal + wizard (CT114 Traefik)
- T015 Validar
report-urireachability desde browser público - T016 Documentar excepções CSP se libs externas exigirem
Fase E — Resposta operacional (opcional)
- T017 Auto-ticket regras abuso
- T018 Push ntfy em
security.input_blockedcritical - T019 Retenção 90 dias + purge
security.*antigos
Critérios de aceitação
- Browser com CSP activo envia violação → evento visível em Eventos em <30s.
- POST domínio
foo<script>alert(1)</script>.com→ 400 VM112 +security.input_blockedno Desk. - Reutilizar token handoff →
security.handoff_rejectedcorrelacionado àsession_id. - Audit Overview VM112 mostra KPIs segurança 24h sem regressão nos domínios existentes.
- Módulo
wizard-securityOFF → card oculto; APIs semsecurity_summary. - Nenhum webhook contém senha nem token handoff completo (auditoria manual + teste).
- Mesma sessão: funil (
session.started) + evento segurança partilhamsession_idno detalhe.
Testes
# CSP report (simulado)
curl -s -X POST https://desk.ligbox.com.br/api/v1/security/csp-report \
-H 'Content-Type: application/csp-report' \
-d '{"csp-report":{"document-uri":"https://onboard.ligbox.com.br/onboard","violated-directive":"script-src","blocked-uri":"https://evil.com/x.js"}}'
# Input blocked (após Fase B)
curl -s -X POST https://onboard.ligbox.com.br/api/.../validate \
-d '{"domain":"x\"; DROP TABLE--"}'
# → 400 + evento no Desk
# Summary Desk
curl -s -H "Authorization: Bearer $TOKEN" \
"https://desk.ligbox.com.br/api/v1/security/summary?tenant_id=1"
Fora de escopo (v1)
- WAF comercial (Cloudflare WAF rules — futuro)
- SIEM externo (export syslog)
- Pentest automatizado no wizard
- Substituir sessionStorage por Web Crypto / Credential Management API
- Segurança Carbonio pós-provisionamento (Spec separada)
Relação com specs existentes
| Spec | Relação |
|---|---|
| 016 | Handoff + sessionStorage — Via 1 auditada, senha nunca no webhook |
| 014 | Relógio por fase — mesma sessão, timeline paralela segurança |
| 015 | Módulo wizard-security |
| 017 | Purge — independente; não apagar security.* antes de retenção |
| 010 | Assist/takeover — técnico vê alertas segurança na sessão assistida |
Conclusão
A Spec 021 define as vias de cibersegurança dos processos do wizard (credenciais, inputs, CSP, handoff) com telemetria em tempo real no VM122 — Audit Overview, Infra 2 e Eventos — sem confundir protecção (HTTPS, handoff, React) com visibilidade operacional (o que o Roger precisa para operar e reagir).
Próximo passo: Fase A (ingestão VM122) — pode começar sem alterações no wizard; Fase B liga a detecção activa na VM112.