E10 · Siete casos
5 minEjecuta el bloque exposición.
Listo cuando: 7/7 casos conferem com a spec y saída: 0.
Clase 4 · 18 min
Por defecto, solo la propia página y las del mismo origin ven la tool. Un iframe de otro origin solo aparece para la página superior con tres consentimientos, y un encabezado lo apaga todo. En esta clase mides los siete casos en Chromium y pones Permissions-Policy: tools=() en las páginas que no necesitan WebMCP.
Comenzar la clase
Objetivo: medir quién ve cada tool (mismo origin, iframe, exposedTo, fromOrigins) y apagar WebMCP con Permissions-Policy donde no debe existir.
Haz clic en cada uno. Top = la página principal; iframe = una página de otro origen dentro de ella.
Medido en Chromium 156.0.8078.4 con la flag de prueba de WebMCP (experimental al 19 de octubre de 2026). La sección de fronteras de origen de la spec (§6.3.4) todavía es solo una nota pendiente.
El topo corre en 127.0.0.1 en un puerto y el iframe en 127.0.0.1 en otro puerto. Misma máquina, puerto distinto: origen distinto.
cd ~/projetos/formacao-webmcp-seguranca-v72/kit node scripts/exposicao.mjs; echo "saída: $?"
<!doctype html>
<!-- filho.html — a página dentro do iframe (pode ser de outra origem). Tenta registrar uma ferramenta.
Parâmetro (só para o laboratório): ?exposto=<origem> vira registerTool(..., { exposedTo: [<origem>] }) -->
<meta charset="utf-8">
<title>iframe</title>
<script>
(async () => {
const q = new URLSearchParams(location.search);
const mc = document.modelContext;
let estado = 'sem WebMCP';
if (mc) {
try {
const opcoes = q.get('exposto') ? { exposedTo: [q.get('exposto')] } : {};
await mc.registerTool({ name: 'ferramenta_iframe', description: 'Ferramenta do iframe.',
inputSchema: { type: 'object', properties: {} }, execute: async () => ({ ok: true }) }, opcoes);
estado = 'registrou';
} catch (e) { estado = 'recusou: ' + e.name; }
}
parent.postMessage({ iframe: estado }, '*');
})();
</script>== Chromium 156.0.8078.4 (Playwright) · modo: nativo confere 0 · iframe da MESMA origem, sem nada → vê: mesma origem é o padrão confere A · iframe de outra origem, sem allow="tools" → iframe recusado (NotAllowedError) confere B · allow="tools", sem exposedTo → topo não vê confere C · allow + exposedTo:[topo], topo sem fromOrigins → topo não vê confere D · allow + exposedTo:[topo] + fromOrigins:[iframe] → topo VÊ a ferramenta do iframe confere E · topo com Permissions-Policy: tools=() → topo e iframe recusados confere F · exposedTo com origem http:// pública → iframe recusado (SecurityError) 7/7 casos conferem com a spec saída: 0
Solo en el caso D la página superior ve la tool del iframe, y el resultado trae su origen (ferramenta_iframe@http://127.0.0.1:…). El agente puede usar ese campo para no confundir de quién es la tool.
Si la tool es solo de tu página, no uses exposedTo. El mismo origen ya la ve, y ningún otro la necesita.
Widget de chat, anuncio, video: un iframe de otro origen sin allow="tools". Así no registra ninguna tool en tu documento.
Inicio de sesión, pago, privacidad: envía Permissions-Policy: tools=(). La spec (§6.4.1) dice que esto protege incluso de un script inyectado o de una dependencia comprometida, porque vale antes de que corra cualquier script.
Ver la tool no significa poder hacerlo todo. El backend sigue comprobando quién es la persona y qué puede hacer, igual que con el botón.
El servidor del kit envía tools=() en la página de privacidad y nada en la página principal. Al lado, el mismo encabezado en tres servidores comunes.
cd ~/projetos/formacao-webmcp-seguranca-v72/kit node scripts/servir.mjs & P=$! until curl -s -o /dev/null http://127.0.0.1:8742/; do sleep 0.3; done curl -sI http://127.0.0.1:8742/privacidade.html | grep -i '^permissions-policy' curl -sI http://127.0.0.1:8742/ | grep -ci '^permissions-policy' kill $P; echo "saída: $?"
location = /privacidade.html {
add_header Permissions-Policy "tools=()" always;
}// antes do express.static
app.use('/privacidade.html', (req, res, next) => {
res.set('Permissions-Policy', 'tools=()');
next();
});/privacidade.html Permissions-Policy: tools=()
página em http://127.0.0.1:8742/ Permissions-Policy: tools=() 0 saída: 0
La página de privacidad manda tools=(); la principal manda 0 encabezados Permissions-Policy (necesita la API).
Medir y apagar.
Ejecuta el bloque exposición.
Listo cuando: 7/7 casos conferem com a spec y saída: 0.
Ejecuta el bloque encabezado.
Listo cuando: Permissions-Policy: tools=() en la página de privacidad y 0 en la principal.
Elige las páginas de tu sitio que no registran tools (login, pago, privacidad), configura el encabezado en tu servidor y revisa cada una con curl -sI [dirección de la página] | grep -i permissions-policy.
Listo cuando: Cada página de la lista responde con permissions-policy: tools=().
Pregunta 1 de 4
Un iframe de otro origen registró con exposedTo apuntando al documento superior, pero el documento superior no lo ve. ¿Qué falta?competencia
Pregunta 2 de 4
¿Qué página debe mandar Permissions-Policy: tools=()?
Pregunta 3 de 4
¿Qué pasa con exposedTo: ['http://exemplo.com']?
Pregunta 4 de 4
La tool aparece para el documento superior. ¿Eso autoriza cualquier acción de ella?
Elige una alternativa. La explicación aparece después de tu intento.