Skip to content
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

fix: insecure iframe messaging #297

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/transports/PostMessageIframeTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ class PostMessageIframeTransport extends Transport {
public uri: string;
public frame: undefined | null | Window;
public postMessageID: string;
public origin: string;

constructor(uri: string) {
constructor(uri: string, origin?: string) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
constructor(uri: string, origin?: string) {
constructor(uri: string, origin: string) {

super();
this.uri = uri;
this.origin = origin || new URL(uri).origin;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome thanks for doing this. The only thing here is that we're going to opt for a breaking change here.

We're going to rm the default, because defaulting to origin can be a hidden breaking change to people using this in prod.

We'll do a maj. verson bump which will force people to explicitly update their clients to set what domain they'd like to use this against, when using postmessage transport.

Once this lands the team will bump the versions of generator and any other ecosystem consumers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.origin = origin || new URL(uri).origin;
this.origin = origin;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit message for these changes should be in the following format for semantic release

fix: patch security hole for post message iframe transport. this change forces consumers to
explicitly set the transport's acceptable origins. Improving the security using the transport.

BREAKING CHANGE: transport now takes second argument and requires origin be set for filtering
post message request.

this.postMessageID = `post-message-transport-${Math.random()}`;
}
public createWindow(uri: string): Promise<Window | null> {
Expand All @@ -28,7 +30,8 @@ class PostMessageIframeTransport extends Transport {
});
}
private messageHandler = (ev: MessageEvent) => {
this.transportRequestManager.resolveResponse(JSON.stringify(ev.data));
if (ev.origin === this.origin)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (ev.origin === this.origin)
if (ev.orgin === this.origin || ev.origin === "*")

this.transportRequestManager.resolveResponse(JSON.stringify(ev.data));
}
public connect(): Promise<any> {
const urlRegex = /^(http|https):\/\/.*$/;
Expand All @@ -46,7 +49,7 @@ class PostMessageIframeTransport extends Transport {
const prom = this.transportRequestManager.addRequest(data, null);
const notifications = getNotifications(data);
if (this.frame) {
this.frame.postMessage((data as IJSONRPCData).request, "*");
this.frame.postMessage((data as IJSONRPCData).request, this.origin);
this.transportRequestManager.settlePendingRequest(notifications);
}
return prom;
Expand Down
9 changes: 6 additions & 3 deletions src/transports/PostMessageWindowTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ class PostMessageTransport extends Transport {
public uri: string;
public frame: undefined | null | Window;
public postMessageID: string;
public origin: string;

constructor(uri: string) {
constructor(uri: string, origin?: string) {
super();
this.uri = uri;
this.origin = origin || new URL(uri).origin;
this.postMessageID = `post-message-transport-${Math.random()}`;
}

Expand All @@ -36,7 +38,8 @@ class PostMessageTransport extends Transport {
}

private messageHandler = (ev: MessageEvent) => {
this.transportRequestManager.resolveResponse(JSON.stringify(ev.data));
if (ev.origin === this.origin)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (ev.origin === this.origin)
if (ev.origin === this.origin || ev.origin === "*")

this.transportRequestManager.resolveResponse(JSON.stringify(ev.data));
}

public connect(): Promise<any> {
Expand All @@ -55,7 +58,7 @@ class PostMessageTransport extends Transport {
const prom = this.transportRequestManager.addRequest(data, null);
const notifications = getNotifications(data);
if (this.frame) {
this.frame.postMessage((data as IJSONRPCData).request, this.uri);
this.frame.postMessage((data as IJSONRPCData).request, this.origin);
this.transportRequestManager.settlePendingRequest(notifications);
}
return prom;
Expand Down