diff --git a/index.bs b/index.bs index ce4b956..6adac6c 100644 --- a/index.bs +++ b/index.bs @@ -1883,11 +1883,124 @@ This creates a personalization-to-fingerprinting pipeline where sites can extrac
- TODO: Document risks and implications of [=agents=] carrying state from one origin to another. Detail how tools executed on one origin may carry state from another origin, potentially leading to data leakage or same-origin policy bypasses if not handled securely by the [=user agent=]. This section should probably talk about the WebMCP permissions policy and other cross-origin opt in mechanisms. -
+The Same-Origin Policy (SOP) is the foundational security boundary of the web platform, isolating +documents of different [=origins=] so that one [=origin=] cannot inspect or manipulate the state of +another without explicit consent. + +In WebMCP, a registered tool's {{ModelContextTool/execute}} callback always runs within the +registering {{Document}}'s execution context, with full access to that [=origin=]'s DOM, storage, +and ambient credentials. Consequently, allowing a cross-origin {{Document}} in the frame tree to +discover a tool ({{ModelContext/getTools()}}), invoke it ({{ModelContext/executeTool()}}), and +receive its serialized return value crosses a privilege boundary. Without strict enforcement, a +malicious frame (either a main frame or an embedded frame) could silently invoke privileged +operations or extract sensitive state from another [=origin=]. + +document.{{Document/modelContext}}.{{ModelContext/registerTool()}} is only
+visible to and executable by {{Document}}s that are [=same origin=] with the registering
+{{Document}} (tool owner). Cross-origin {{Document}}s cannot discover, observe
+{{ModelContext/toolchange}} events for, or execute a tool unless three independent access-control
+gates are satisfied:
+
+allow="tools"): Access
+ to all WebMCP APIs ({{ModelContext/registerTool()}}, {{ModelContext/getTools()}}, and
+ {{ModelContext/executeTool()}}) is gated behind the "{{tools}}" [=policy-controlled feature=],
+ whose [=policy-controlled feature/default allowlist=] is [=default
+ allowlist/'self'=]. Consequently, a cross-origin <{iframe}> cannot register or expose
+ tools—nor will an ancestor's {{ModelContext/getTools()}} traversal inspect that subframe—unless
+ the embedding {{Document}} explicitly delegates the "{{tools}}" feature to the subframe via
+ <iframe allow="tools">.
+ allow="tools" and has exposed
+ a tool to its parent [=origin=] via {{ModelContextRegisterToolOptions/exposedTo}},
+ {{ModelContext/getTools()}} only returns tools from [=same origin=] {{Document}}s by default. To
+ discover tools from a cross-origin descendant [=navigable=], the calling {{Document}} must also
+ explicitly list the target [=origin=] in {{ModelContextGetToolOptions/fromOrigins}}.
+