-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accessing contentWindow on cross domain iframes with static js interop doesn't work #54938
Comments
|
cc @nshahan @fishythefish - I believe this wouldn't affect the dart2js compiler due to differences in how we lookup the interceptor there, but it's worth checking nonetheless. |
Can repro similar behavior in JS trying to access properties that don't exist on a cross domain iframe. var frame = document.createElement("iframe")
frame.src = "https://some_other_domain.com";
frame.contentWindow["property_that_does_not_exist"]; // throws however var frame = document.createElement("iframe")
frame.src = "https://some_other_domain.com";
frame.contentWindow["property_that_does_not_exist"] = 1;
frame.contentWindow["property_that_does_not_exist"]; // doesn't throw So it is checking to see if it is a dart object or a js object, but that can't be done without an exception being thrown on the Window object since it is cross domain. Perhaps the an exception looking up the symbol could be handled and then the symbol set to null in the catch for a minimal performance penalty so it only happens first time around? |
@jezell Thanks for the helpful report! @sigmundch I agree with your assessment. The code referenced here is only run in DDC. If dart2js has a problem finding the interceptor for cross origin values it will need to be addressed separately. Would dart2js allow for apps from different frames to pass Dart values between them or are they forced to do some type of conversion to a JavaScript interop value first? If there isn't any Dart to Dart object passing allowed then in DDC it seems like the right thing to do here is to treat any cross origin value as a |
cc @rakudrama precisely - I think treating it as JSObject makes sense. Anything sent between separate apps (whether they are on the same page or separate iframes) will need to go through interop, and as a result is treated as JS values. Even if you send raw unboxed value through the interop boundary (bypassing some interop conversions), all RTI data is isolated, so it will be viewed as a JS object. |
Similar issue: #54443. It's possible we may come across other issues here even if this specific bug is fixed in the RTI. |
The Flutter sidebar in VS Code is failing with what seems like the same error: The sidebar (part of Flutter DevTools) is hosted inside a sandboxed iframe in VS Code and trying to communicate with its parent using If this isn't a simple fix, are there any reasonable workarounds we could apply to that code? |
@DanTup As a workaround, I believe you can cast to the old dart:html version which doesn't have the problem. |
This is a workaround for dart-lang/sdk#54938 because the package:web version of postMessage causes security exceptions. Fixes Dart-Code/Dart-Code#5049
That issue seems more like #54443 considering it's dart2js, but it's a similar issue around cross-domain frames. The error seems to arise from Looking at the source I wonder if it's |
@srujzs you can repro this using VS Code and Flutter master (just try to load the Flutter Sidebar), but it's probably not very easy to debug that way (however I don't know if it can easily be reproduced outside of it because of the sandboxed iframe etc.). You can click Help -> Toggle Developer Tools in VS Code to open the Chrome DevTools. I'll see if getProperty helps. |
I tried all of these, but no change: final parent = window.parent;
if (parent != null) {
parent.postMessage(message.jsify(), targetOrigin.toJS);
} (window.parent as JSObject?)
?.callMethod('postMessage'.toJS, message.jsify(), targetOrigin.toJS); void postMessage(Object? message, String targetOrigin) {
(window as JSObject)
.getProperty<JSObject?>('parent'.toJS)
?.callMethod('postMessage'.toJS, message.jsify(), targetOrigin.toJS);
} var parent = (window as JSObject).getProperty<JSObject?>('parent'.toJS);
if (parent != null) {
parent.callMethod('postMessage'.toJS, message.jsify(), targetOrigin.toJS);
} I don't know if any of them were exactly what you were suggesting though. |
Oh by the way, you can get at the source from your Flutter SDK checkout (be on master, not stable):
(let me know if I should move this to another issue since it sounds like it might not be the same) For convenience, here's the bit of code I suspect you care about: A.DartToolingApiImpl_DartToolingApiImpl$postMessage_closure.prototype = {
call$1(message) {
var t1 = type$.nullable_JavaScriptObject._as(type$.JavaScriptObject._as(self.window).parent);
if (t1 != null)
A.callMethod(t1, "postMessage", [A.jsify(message), "*"], type$.void);
},
$signature: 7
}; |
(following up in flutter/devtools#7476 - thanks for all the details!) |
This is still blocking us from being able to move to package:web. |
Can we bump priority of fixing this? cc @natebiggs |
Yeah, I don't see a usable workaround for this like we had with the |
@srujzs and I talked about this earlier. We've prioritized finding a solution here. We want to make sure that it's an separate opt-in API for cases where a user knows they might be dealing with a x-domain object. Given the need for extra interceptor logic/a wrapper we want to make sure we don't degrade other interop use cases. |
Closes dart-lang/sdk#54443 Closes dart-lang#247 Closes dart-lang/sdk#54938 Since cross-origin objects have limitations around access, wrappers are introduced to do the only safe operations. Extension methods are added to get instances of these wrappers.
A security exception is thrown when trying to access the contentWindow property of a cross domain iframe using static interop:
Given the same setup using non static interop, the call succeeds:
It blows up here in the rtti:
With this message:
It appears something about the rtti check is accessing a property that is locked down on cross domain frames when trying to get the Window object, but I'm unable to step deeper into the stack in the devtools to see exactly the property that is being checked.
The text was updated successfully, but these errors were encountered: