E22 · Auditoria do kit
10 minCom os furos das aulas 2 e 3 consertados, rode o bloco auditar e abra o relatorio-seguranca.md.
Pronto quando: AUDITORIA: 6/6 ok e saída: 0.
Aula 8 · 20 min
Seis verificações, uma por aula, numa execução só e com relatório datado. Você roda a auditoria no kit, planta um segredo para ver a quebra ser pega e sai com o plano de revisão: a spec muda, as dependências mudam, e a auditoria roda de novo.
Começar a aula
Objetivo: rodar a auditoria completa (página, fallback, exposição, catálogo, servidor, segredos), ver uma quebra ser pega e sair com o plano datado.
Uma por aula do curso. Clique em cada uma.
Web Bot Auth (aula 6) não entra: é decisão de política, conferida na ficha e no politica-bots.md.
Com os dois furos consertados (aulas 2 e 3). Grava kit/relatorio-seguranca.md com data.
cd ~/projetos/formacao-webmcp-seguranca-v72/kit node scripts/auditar.mjs; echo "saída: $?"
// auditar.mjs — a auditoria de segurança do curso inteiro numa execução (aula 8).
// 6 verificações, cada uma de uma aula; grava relatorio-seguranca.md com data e resultado.
// 1 página checar.mjs: texto de terceiro marcado; ação com consequência pede confirmação (aulas 2–3)
// 2 fallback a página funciona sem WebMCP (o caso da maioria dos visitantes)
// 3 exposição toda página .html que não é a index manda Permissions-Policy com tools=() (aula 4)
// 4 catálogo ameacas.mjs sem achados (aula 7)
// 5 servidor atacar-mcp.mjs seguro: 0 de 6 ataques passam (aula 5)
// 6 segredos segredos.mjs na pasta do kit: 0 segredos (aula 5)
// Uso: node scripts/auditar.mjs (PAGINA=<pasta> e CATALOGO=<arquivo> para a sua cópia)
// Saída 0 = 6/6; 1 = alguma falhou.
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);== 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
O número de arquivos lidos muda com o que você acrescentar ao kit. O que conta é a última linha.
Um arquivo esquecido com token dentro da pasta da página. O bloco planta, audita e apaga.
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.mjsFALHA 6 segredos: 71 arquivos lidos · 1 segredo AUDITORIA: 5/6 ok · relatório: relatorio-seguranca.md saída: 1
Saída 1: dá para usar a auditoria como portão antes de publicar (no CI ou num hook de pre-push).
Uma cópia local da sua página que registre as ferramentas e marque document.documentElement.dataset.webmcp no fim. PAGINA=[pasta] troca a pasta; CANARIO e CONFIRMAR trocam o canário e o seletor do seu diálogo.
CATALOGO=[arquivo] aponta o módulo com as definições, se não for ferramentas.mjs.
O atacar-mcp.mjs ataca o servidor do kit. Para o seu, copie os seis ataques e troque o subir() pela URL do seu servidor de teste, com tokens de teste do seu provedor.
A cada ferramenta nova, a cada atualização de dependência e quando a spec mudar. O WebMCP é rascunho: o origin trial vai até o Chrome 156 (em 19/10/2026) e a API já mudou de nome uma vez, de navigator.modelContext para document.modelContext.
Quatro entregas, oito aulas. Clique num exercício para ver o "pronto quando".
Aceite que não há filtro e marque o que vem de visitante.
Confirmação com alvo e efeito, exposição medida, tools=() onde não precisa.
Audiência, escopo, handle com dono; assinatura conferida.
Modele as ameaças e rode a bateria a cada mudança.
Cada par de aulas usa o kit consertado da anterior.
Escolha a data de início e quanto tempo você tem por semana.
A auditoria no kit e no seu site.
Com os furos das aulas 2 e 3 consertados, rode o bloco auditar e abra o relatorio-seguranca.md.
Pronto quando: AUDITORIA: 6/6 ok e saída: 0.
Rode o bloco quebra.
Pronto quando: FALHA 6 segredos, AUDITORIA: 5/6 ok e saída: 1; depois do rm, a auditoria volta a 6/6.
Rode a auditoria com PAGINA e CATALOGO do seu site, gere o plano acima e marque no calendário a próxima revisão.
Pronto quando: PAGINA=[sua pasta] node scripts/auditar.mjs e depois head -1 relatorio-seguranca.md → # Relatório de segurança — [data de hoje]; ls [sua pasta de downloads]/plano-*.ics → o arquivo do plano.
Pergunta 1 de 4
A auditoria deu 5/6 com FALHA 6 segredos. O que fazer antes de publicar?competência
Pergunta 2 de 4
Por que a verificação 2 abre a página SEM WebMCP?
Pergunta 3 de 4
Quando a auditoria precisa rodar de novo?
navigator.modelContext para document.modelContext).navigator.modelContext para document.modelContext).Rever: Auditar o seu sitePergunta 4 de 4
Que aula do curso a auditoria NÃO verifica automaticamente?
Escolha uma alternativa. A explicação aparece depois da sua tentativa.