dotnet / dotnet/aspnetcore

Blazor raises Permission Denied error when calling JS function with a cross-origin Window object as parameter

Open
#48,521 8 comments 0 reactions 0 assignees View on GitHub
area-blazor feature-blazor-jsinterop
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

My app keeps an `IJSObjectReference` instance of a `IWindow` object obtained from `window.opener`. The `opener` is from another origin so most operation throws Permission Denied error and I only intend to use it for `postMessage`. However if I pass it to any JS function, Blazor attempts to call `Object.prototype.hasOwnProperty` on it and causes the app to crash. This also happens to `iframe`s.

> Blocked a frame with origin "https://localhost:44357" from accessing a cross-origin frame.

![image](https://github.com/dotnet/aspnetcore/assets/6388546/969c3ec6-f21e-4d10-b414-0fe51d8aa37b)

```js
globalThis.wasmInterop = new class {

getOpener() {
return globalThis.parent;
}

sendReadyMessage(window, op) {
window.postMessage({
op,
});
}

}();
```

```cs
@inject IJSRuntime Js;
// ...

IJSObjectReference? opener;

protected override async Task OnInitializedAsync()
{
opener = await Js.InvokeAsync("wasmInterop.getOpener");
}

async Task SendMessageAsync()
{
ArgumentNullException.ThrowIfNull(opener);

// This one is fine
await opener.InvokeVoidAsync("postMessage", "hello", "*");

// This one raises the error
await Js.InvokeVoidAsync("wasmInterop.sendReadyMessage", opener, "hello");
}
```

Interestingly, invoking the reference directly doesn't cause a problem. It only happens when it is a function parameter. I traced the source code back to [this line in `ElementReferenceCapture.ts`](https://github.com/dotnet/aspnetcore/blob/81666eef98bd9e8c4d95c1478ebe4d4ba77e61a3/src/Components/Web.JS/src/Rendering/ElementReferenceCapture.ts#LL22C1-L22C1):

```ts
DotNet.attachReviver((key, value) => {
if (value && typeof value === 'object' && Object.prototype.hasOwnProperty.call(value, elementRefKey) && typeof value[elementRefKey] === 'string') {
return getElementByCaptureId(value[elementRefKey]);
} else {
return value;
}
});
```

### Expected Behavior

Ideally `hasOwnProperty` should not be called, or at least Exception should be handled.

### Steps To Reproduce

Github repo for the above code: https://github.com/datvm/BlazorHasOwnPropertyBugDemo, you should run both website, the bug can be seen by running the ASP.NET Core website on the Index page, click "Send message" button in the iframe.

### Exceptions (if any)

_No response_

### .NET Version

7.0.302

### Anything else?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.