'SecurityError: Blocked a frame with origin ... from accessing a cross-origin frame' when opening Flutter app in iframe
- Dominant language
- Dart
- Stars
- 224
- Forks
- 94
- Avg merge
- 4d 3h
- Merged PRs (30d)
- 2
Description
## Steps to Reproduce ##
1. Create a Flutter project, replace `main.dart` with the code below.
2. Debug in Chrome.
3. Create an HTML file with an iframe to load that Flutter app.
4. Open the page locally in Chrome or Firefox, view the console.
**Expected:** No errors.
**Actual:**
```
Unhandled error detected in the injected client.js script.
You can disable this script in webdev by passing --no-injected-client if it
is preventing your app from loading, but note that this will also prevent
all debugging and hot reload/restart functionality from working.
The original error is below, please file an issue at
https://github.com/dart-lang/webdev/issues/new and attach this output:
SecurityError: Blocked a frame with origin "http://localhost:40002" from accessing a cross-origin frame.
Error: Blocked a frame with origin "http://localhost:40002" from accessing a cross-origin frame.
at http://localhost:40002/dwds/src/injected/client.js:24290:31
at _wrapJsFunctionForAsync_closure.$protected (http://localhost:40002/dwds/src/injected/client.js:3475:15)
at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:40002/dwds/src/injected/client.js:11564:12)
at _awaitOnObject_closure.call$1 (http://localhost:40002/dwds/src/injected/client.js:11552:32)
at StaticClosure._rootRunUnary (http://localhost:40002/dwds/src/injected/client.js:3837:18)
at _CustomZone.runUnary$2$2 (http://localhost:40002/dwds/src/injected/client.js:12970:39)
at _Future__propagateToListeners_handleValueCallback.call$0 (http://localhost:40002/dwds/src/injected/client.js:11996:51)
at Object._Future__propagateToListeners (http://localhost:40002/dwds/src/injected/client.js:3617:93)
at _Future._completeWithValue$1 (http://localhost:40002/dwds/src/injected/client.js:11822:9)
at _AsyncAwaitCompleter.complete$1 (http://localhost:40002/dwds/src/injected/client.js:11535:14)
at Object._asyncReturn (http://localhost:40002/dwds/src/injected/client.js:3447:17)
at http://localhost:40002/dwds/src/injected/client.js:8749:24
at _wrapJsFunctionForAsync_closure.$protected (http://localhost:40002/dwds/src/injected/client.js:3475:15)
at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:40002/dwds/src/injected/client.js:11564:12)
at _awaitOnObject_closure.call$1 (http://localhost:40002/dwds/src/injected/client.js:11552:32)
at StaticClosure._rootRunUnary (http://localhost:40002/dwds/src/injected/client.js:3837:18)
at _CustomZone.runUnary$2$2 (http://localhost:40002/dwds/src/injected/client.js:12970:39)
at _Future__propagateToListeners_handleValueCallback.call$0 (http://localhost:40002/dwds/src/injected/client.js:11996:51)
at Object._Future__propagateToListeners (http://localhost:40002/dwds/src/injected/client.js:3617:93)
at _Future._completeWithValue$1 (http://localhost:40002/dwds/src/injected/client.js:11822:9)
at _AsyncAwaitCompleter.complete$1 (http://localhost:40002/dwds/src/injected/client.js:11535:14)
at Object._asyncReturn (http://localhost:40002/dwds/src/injected/client.js:3447:17)
at http://localhost:40002/dwds/src/injected/client.js:24760:24
at _wrapJsFunctionForAsync_closure.$protected (http://localhost:40002/dwds/src/injected/client.js:3475:15)
at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:40002/dwds/src/injected/client.js:11564:12)
at _awaitOnObject_closure.call$1 (http://localhost:40002/dwds/src/injected/client.js:11552:32)
at StaticClosure._rootRunUnary (http://localhost:40002/dwds/src/injected/client.js:3837:18)
at _CustomZone.runUnary$2$2 (http://localhost:40002/dwds/src/injected/client.js:12970:39)
at _Future__propagateToListeners_handleValueCallback.call$0 (http://localhost:40002/dwds/src/injected/client.js:11996:51)
at Object._Future__propagateToListeners (http://localhost:40002/dwds/src/injected/client.js:3617:93)
at _Future._completeWithValue$1 (http://localhost:40002/dwds/src/injected/client.js:11822:9)
at _AsyncAwaitCompleter.complete$1 (http://localhost:40002/dwds/src/injected/client.js:11535:14)
at Object._asyncReturn (http://localhost:40002/dwds/src/injected/client.js:3447:17)
at http://localhost:40002/dwds/src/injected/client.js:24737:24
at _wrapJsFunctionForAsync_closure.$protected (http://localhost:40002/dwds/src/injected/client.js:3475:15)
at _wrapJsFunctionForAsync_closure.call$2 (http://localhost:40002/dwds/src/injected/client.js:11564:12)
at _awaitOnObject_closure.call$1 (http://localhost:40002/dwds/src/injected/client.js:11552:32)
at StaticClosure._rootRunUnary (http://localhost:40002/dwds/src/injected/client.js:3837:18)
at _CustomZone.runUnary$2$2 (http://localhost:40002/dwds/src/injected/client.js:12970:39)
at _Future__propagateToListeners_handleValueCallback.call$0 (http://localhost:40002/dwds/src/injected/client.js:11996:51)
at Object._Future__propagateToListeners (http://localhost:40002/dwds/src/injected/client.js:3617:93)
at _Future._completeWithValue$1 (http://localhost:40002/dwds/src/injected/client.js:11822:9)
at _Future__asyncCompleteWithValue_closure.call$0 (http://localhost:40002/dwds/src/injected/client.js:11924:18)
at StaticClosure._rootRun (http://localhost:40002/dwds/src/injected/client.js:3822:16)
at _CustomZone.run$1$1 (http://localhost:40002/dwds/src/injected/client.js:12962:39)
at _CustomZone.runGuarded$1 (http://localhost:40002/dwds/src/injected/client.js:12905:14)
at _CustomZone_bindCallbackGuarded_closure.call$0 (http://localhost:40002/dwds/src/injected/client.js:13100:25)
at Object._microtaskLoop (http://localhost:40002/dwds/src/injected/client.js:3681:24)
at StaticClosure._startMicrotaskLoop (http://localhost:40002/dwds/src/injected/client.js:3687:11)
at _AsyncRun__initializeScheduleImmediate_internalCallback.call$1 (http://localhost:40002/dwds/src/injected/client.js:11440:9)
at invokeClosure (http://localhost:40002/dwds/src/injected/client.js:1274:26)
at MutationObserver. (http://localhost:40002/dwds/src/injected/client.js:1293:18)
```
It does not impact work, but it should not be thrown to users.
main.dart
```dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Container(color: Colors.amber),
);
}
}
```
outer.html
```html
```
flutter doctor -v
```
[✓] Flutter (Channel stable, 3.0.4, on Ubuntu 20.04.4 LTS 5.14.0-1044-oem, locale en_US.UTF-8)
• Flutter version 3.0.4 at /home/alexey/snap/flutter/common/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 85684f9300 (12 days ago), 2022-06-30 13:22:47 -0700
• Engine revision 6ba2af10bb
• Dart version 2.17.5
• DevTools version 2.12.2
[!] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
• Android SDK at /home/alexey/Android/Sdk
✗ cmdline-tools component is missing
Run `path/to/sdkmanager --install "cmdline-tools;latest"`
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/linux#android-setup for more details.
[✓] Chrome - develop for the web
• Chrome at google-chrome
[✓] Linux toolchain - develop for Linux desktop
• clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
• cmake version 3.10.2
• ninja version 1.8.2
• pkg-config version 0.29.1
[✓] Android Studio (version 2021.2)
• Android Studio at /home/alexey/bin/android-studio
• Flutter plugin version 68.1.2
• Dart plugin version 212.5744
• Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
[✓] VS Code (version 1.68.1)
• VS Code at /usr/share/code
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (2 available)
• Linux (desktop) • linux • linux-x64 • Ubuntu 20.04.4 LTS 5.14.0-1044-oem
• Chrome (web) • chrome • web-javascript • Google Chrome 103.0.5060.53
[✓] HTTP Host Availability
• All required HTTP hosts are available
! Doctor found issues in 1 category.
```

Contributor guide
Research direction
Reproduce the Flutter app in main.dart inside the iframe from outer.html and inspect the injected client.js stack trace while debugging in Chrome or Firefox. Start with the webdev injected client path and compare behavior with --no-injected-client. Done means the cross-origin SecurityError is no longer exposed to users while debugging and hot reload/restart still work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, flutter, javascript
- Domain
- cli, devtools, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100