Add sandbox attribute to extension iframe in DevTools. (#9967)

* Add sandbox attribute to extension iframe in DevTools.

This change grants these permissions:
- `allow-scripts`: enables extension JS / Wasm execution.
- `allow-forms`: permits standard form interactions.
- `allow-downloads`: allows extensions to export files/logs.
- `allow-popups` & `allow-popups-to-escape-sandbox`: allows opening
   external links.

This does not grant `allow-same-origin` permission, so extensions can't
access the parent window's DOM, cookies, or local storage.

* Add pull request URL

* Move string to top-level variable

* Add allow-same-origin to DevTools extension iframe sandbox

Flutter Web extensions require same-origin access for flutter.js to
initialize Service Workers and web storage without throwing a
SecurityError.

This is still secure because the extension must be enabled, and
the sandbox prevents top-level navigation, popups, and modal hijacking.

* Add a timestamp to the extension placeholder

This is to ensure "force reload extension" works.

* Update extension debugging skill

* Revert "Update extension debugging skill"

This reverts commit 4cebdf8cb158d1f8b15e86cd1c5ced930ec75eee.

* Specify permissions for iframe in comment

* Revert "Add a timestamp to the extension placeholder"

This reverts commit 177df19436b9d0face3d23c2c5d15cf25c37940a.
diff --git a/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart b/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart
index ab96f86..9d28185 100644
--- a/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart
+++ b/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart
@@ -59,6 +59,16 @@
 ''';
 }
 
+/// The sandbox permissions granted to embedded extension iframes.
+///
+/// Configures the iframe sandbox to allow:
+/// - Script execution (`allow-scripts`)
+/// - Origin-based features like local storage and service workers (`allow-same-origin`)
+/// - Form submissions and downloads (`allow-forms`, `allow-downloads`)
+/// - Unrestricted popup windows and links (`allow-popups`, `allow-popups-to-escape-sandbox`)
+const _extensionSandboxRules =
+    'allow-scripts allow-same-origin allow-forms allow-downloads allow-popups allow-popups-to-escape-sandbox';
+
 class EmbeddedExtensionControllerImpl extends EmbeddedExtensionController
     with AutoDisposeControllerMixin {
   EmbeddedExtensionControllerImpl(super.extensionConfig);
@@ -123,7 +133,8 @@
       // This url is safe because we built it ourselves and it does not include
       // any user input.
       ..src = extensionUrl
-      ..allow = 'usb';
+      ..allow = 'usb'
+      ..sandbox.value = _extensionSandboxRules;
     _extensionIFrame.style
       ..border = 'none'
       ..height = '100%'
diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
index a54592a..ca70b2c 100644
--- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
+++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md
@@ -91,6 +91,8 @@
 
 * Hide the DevTools extensions menu button in single-screen embedded mode (`EmbedMode.embedOne`) on standard screens.
   [#8507](https://github.com/flutter/devtools/issues/8507)
+* Added iframe sandboxing for embedded DevTools extensions to enforce origin
+  isolation. [#9967](https://github.com/flutter/devtools/pull/9967)
 
 ## Advanced developer mode updates