Seguridad y confianza entre sitio y agente|INEMA.CLUB-PRO

En esta clase vas a

  1. 1Las seis verificaciones y de qué clase viene cada una
  2. 2El informe fechado que graba la auditoría
  3. 3Una rotura plantada a propósito y detectada
  4. 4Tu plan con fechas y la próxima revisión

Objetivo: ejecutar la auditoría completa (página, fallback, exposición, catálogo, servidor, secretos), ver cómo se detecta una rotura y salir con el plan fechado.

01Seis verificaciones

Una por clase del curso. Haz clic en cada una.

Haz clic en cada bloque del diagrama para ver qué hace.

Web Bot Auth (clase 6) no entra: es una decisión de política, que se revisa en la ficha y en politica-bots.md.

02La auditoría del kit

Con los dos fallos corregidos (clases 2 y 3). Guarda kit/relatorio-seguranca.md con la fecha.

Terminal · auditar
cd ~/projetos/formacao-webmcp-seguranca-v72/kit
node scripts/auditar.mjs; echo "saída: $?"
Archivo · kit/scripts/auditar.mjs
// auditar.mjs — la auditoría de seguridad de todo el curso en una sola ejecución (clase 8).
// 6 verificaciones, cada una de una clase; guarda relatorio-seguranca.md con fecha y resultado.
//   1 página      checar.mjs: texto de terceros marcado; la acción con consecuencias pide confirmación (clases 2–3)
//   2 fallback    la página funciona sin WebMCP (el caso de la mayoría de los visitantes)
//   3 exposição   toda página .html que no es index envía Permissions-Policy con tools=() (clase 4)
//   4 catálogo    ameacas.mjs sin hallazgos (clase 7)
//   5 servidor    atacar-mcp.mjs seguro: 0 de 6 ataques pasan (clase 5)
//   6 segredos    segredos.mjs en la carpeta del kit: 0 secretos (clase 5)
// Uso: node scripts/auditar.mjs     (PAGINA=<carpeta> y CATALOGO=<archivo> para tu copia)
// Salida 0 = 6/6; 1 = alguna falló.
import { spawnSync } from 'node:child_process';
import { readdirSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { KIT, pastaPagina, servir, abrir } from '../lib/navegador.mjs';

const node = (...args) => spawnSync(process.execPath, args, { cwd: KIT, encoding: 'utf8', timeout: 240000 });
const ultima = r => (r.stdout || r.stderr || '').trim().split('\n').at(-1);
const res = [];
const anotar = (n, nome, ok, det) => { res.push({ n, nome, ok, det }); console.log(`${ok ? 'ok   ' : 'FALHA'} ${n} ${nome}: ${det}`); };

const pasta = pastaPagina();
const s0 = await abrir('sem');
console.log(`== ${s0.versao.replace(' · modo: sem', '')} · ${new Date().toISOString().slice(0, 10)}`);

let r = node('scripts/checar.mjs');
anotar(1, 'página', r.status === 0, ultima(r));

const fb = await s0.page.evaluate(() => ({ modo: document.documentElement.dataset.webmcp, itens: document.querySelectorAll('li').length }));
anotar(2, 'fallback', fb.modo === 'sem' && fb.itens > 0 && !s0.erros.length, `sem WebMCP: ${fb.itens} itens na tela, ${s0.erros.length} erros de JS`);
await s0.fechar();

const srv = await servir(pasta);
const paginas = readdirSync(pasta).filter(f => f.endsWith('.html') && f !== 'index.html');
const sem = [];
for (const p of paginas) {
  const pp = (await fetch(srv.url + p)).headers.get('permissions-policy') || '';
  if (!/\btools=\(\)/.test(pp)) sem.push(p);
}
await srv.fechar();
anotar(3, 'exposição', sem.length === 0, sem.length ? `sem Permissions-Policy tools=(): ${sem.join(', ')}` : `${paginas.length} página(s) sem ferramenta com tools=()`);

r = node('scripts/ameacas.mjs', process.env.CATALOGO || resolve(pasta, 'ferramentas.mjs'));
anotar(4, 'catálogo', r.status === 0, ultima(r));

r = node('scripts/atacar-mcp.mjs', 'seguro');
anotar(5, 'servidor', r.status === 0, ultima(r));

r = node('scripts/segredos.mjs', '.');
anotar(6, 'segredos', r.status === 0, ultima(r));

const okN = res.filter(x => x.ok).length;
const hoje = new Date().toISOString().slice(0, 10);
writeFileSync(resolve(KIT, 'relatorio-seguranca.md'),
  `# Relatório de segurança — ${hoje}\n\nSpec WebMCP: rascunho CG de 16/10/2026 · MCP 2026-07-28\n\n| # | verificação | resultado | detalhe |\n|---|---|---|---|\n` +
  res.map(x => `| ${x.n} | ${x.nome} | ${x.ok ? 'ok' : 'FALHA'} | ${x.det.replace(/\|/g, '/')} |`).join('\n') +
  `\n\nTotal: ${okN}/6. Rode de novo a cada mudança de ferramenta, de dependência ou da spec.\n`);
console.log(`AUDITORIA: ${okN}/6 ok · relatório: relatorio-seguranca.md`);
process.exit(okN === 6 ? 0 : 1);
Ejemplo del repositorio
== Chromium 156.0.8078.4 (Playwright) · 2026-10-19
ok    1 página: RESULTADO: 0 falhas
ok    2 fallback: sem WebMCP: 4 itens na tela, 0 erros de JS
ok    3 exposição: 1 página(s) sem ferramenta com tools=()
ok    4 catálogo: 5 ferramentas · 0 achados
ok    5 servidor: passaram: 0 de 6
ok    6 segredos: 70 arquivos lidos · 0 segredos
AUDITORIA: 6/6 ok · relatório: relatorio-seguranca.md
saída: 0

El número de archivos leídos cambia según lo que agregues al kit. Lo que cuenta es la última línea.

03Una rotura plantada

Un archivo olvidado con un token dentro de la carpeta de la página. El bloque lo planta, audita y lo borra.

Terminal · rotura
cd ~/projetos/formacao-webmcp-seguranca-v72/kit
printf "export const TOKEN = '%s';\n" $(openssl rand -hex 16) > pagina/config-esquecida.mjs
node scripts/auditar.mjs | tail -2; echo "saída: ${PIPESTATUS[0]}"
rm pagina/config-esquecida.mjs
Ejemplo del repositorio
FALHA 6 segredos: 71 arquivos lidos · 1 segredo
AUDITORIA: 5/6 ok · relatório: relatorio-seguranca.md
saída: 1

Salida 1: puedes usar la auditoría como compuerta antes de publicar (en el CI o en un hook de pre-push).

04Auditar tu sitio

1. Página

Una copia local de tu página que registre las tools y marque document.documentElement.dataset.webmcp al final. PAGINA=[carpeta] cambia la carpeta; CANARIO y CONFIRMAR cambian el canario y el selector de tu diálogo.

05El mapa del curso

Cuatro entregas, ocho clases. Haz clic en un ejercicio para ver el "listo cuando".

Clases 1–2Texto

inyección + marca

3 ejercicios

Texto de terceros encontrado y marcado.

Ver la clase
Clases 3–4Frenos

confirmación + origen

3 ejercicios

Una acción pide a una persona; solo debe verla quien corresponde.

Ver la clase
Clases 5–6Servidor

token + identidad

3 ejercicios

6 ataques bloqueados y política de bots.

Ver la clase
Clases 7–8Auditoría

ficha + batería

3 ejercicios

Ficha 7/7 y auditoría 6/6.

Ver la clase
Al final del cursoSitio y servidor auditados, con informe fechado y fecha de la próxima revisión.
24 ejercicios
Haz clic en un ejercicio para ver qué hacer y el "listo cuando".
  1. 1/4

    Texto

    Acepta que no hay filtro y marca lo que viene de un visitante.

  2. 2/4

    Frenos

    Confirmación con destino y efecto, exposición medida, tools=() donde no hace falta.

  3. 3/4

    Servidor

    Audiencia, scope, handle con dueño; firma verificada.

  4. 4/4

    Auditoría

    Modela las amenazas y ejecuta la batería con cada cambio.

Cada par de clases usa el kit corregido de la anterior.

06Genera tu plan con fechas

Elige la fecha de inicio y cuánto tiempo tienes por semana.

07Práctica

La auditoría en el kit y en tu sitio.

E22 · Auditoría del kit

10 min

Con los fallos de las clases 2 y 3 corregidos, ejecuta el bloque auditar y abre el relatorio-seguranca.md.

Listo cuando: AUDITORIA: 6/6 ok y saída: 0.

E23 · La rotura se detecta

5 min

Ejecuta el bloque rotura.

Listo cuando: FALHA 6 segredos, AUDITORIA: 5/6 ok y saída: 1; después del rm, la auditoría vuelve a 6/6.

E24 · Tu sitio y la fecha

30 min

Ejecuta la auditoría con PAGINA y CATALOGO de tu sitio, genera el plan de arriba y marca en el calendario la próxima revisión.

Listo cuando: PAGINA=[tu carpeta] node scripts/auditar.mjs y después head -1 relatorio-seguranca.md → # Relatório de segurança — [fecha de hoy]; ls [tu carpeta de descargas]/plano-*.ics → el archivo del plan.

08Prueba de la clase

Pregunta 1 de 4

La auditoría dio 5/6 con FALHA en segredos. ¿Qué haces antes de publicar?competencia

09En tres frases

BateríaSeis verificaciones, una ejecución, informe con fecha.
CompuertaLa salida 1 detiene la publicación hasta corregir.
RitmoEjecútala de nuevo con cada tool, dependencia o cambio de la spec.

Para ir más allá

Clase anteriorVolver al inicio del curso