Skip to content

Commit

Permalink
postMessage origin validation for security reasons
Browse files Browse the repository at this point in the history
  • Loading branch information
softvar committed Mar 23, 2017
1 parent f1e9671 commit b630c97
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 9 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ var parent = new AcrossTabs.Parent(config);
* `shouldInitImmediately`: Pass it as `false` to create an instance but initialize it later
* `onHandshakeCallback`: Callback to be called when a successful connection has been established
* `onPollingCallback`: Callback to be called every time a tab is polled for its status
* `origin`: whitelist `origin` for securing `postMessage` communication. It will discard the malicious messages trying to trick the behavior. Eg. http://example.com

| Config Keys | default | accepts |
| --------------------- | -------------- | ----------------------------------------- |
Expand Down Expand Up @@ -158,6 +159,7 @@ var child = new AcrossTabs.Child();
* `onParentDisconnect`: Callback to be invoked when Parent gets disconnected
* `onParentCommunication`: Callback to be invoked whenevr Parent communicates with the child tab
* `isSiteInsideFrame`: If the library is loaded inside an iframe in the child tab, this needs to be set `true` for maintaining proper window/frame(s) references
* `origin`: whitelist `origin` for securing `postMessage` communication. It will discard the malicious messages trying to trick the behavior. Eg. http://example.com

| Config Keys | default | accepts |
| ------------------------- | -------------- | ----------------------------------------- |
Expand Down Expand Up @@ -339,7 +341,6 @@ ES6 source files

* Having a Queue mechanism to deal with loads of async events.
* Promise based `Parent-Child` communication. Will help in sending window specific data to and fro apart from custom data messages.
* Add support for whitelisting `origin` for securing `postMessage` communication. It will discard the malicious messages trying to trick the behavior.
* E2E testing so that the behavior can be tested automatically.
* Maintaining and adding more enhancements as and when required. Open to everyone's suggestions.

Expand Down
10 changes: 9 additions & 1 deletion src/child.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ class Child {
return;
}

// `origin` check for secureity point of view
if (this.config.origin && this.config.origin !== message.origin) {
return;
}

// cancel timeout
window.clearTimeout(this.timeout);

Expand Down Expand Up @@ -210,8 +215,11 @@ class Child {
* @param {String} msg
= */
sendMessageToParent(msg) {
let origin;

if (window.top.opener) {
window.top.opener.postMessage(msg, '*');
origin = this.config.origin || '*';
window.top.opener.postMessage(msg, origin);
}
};

Expand Down
5 changes: 5 additions & 0 deletions src/event-listeners/postmessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ PostMessageListener.onNewTab = (message) => {
return false;
}

// `origin` check for secureity point of view
if (tabUtils.config.origin && tabUtils.config.origin !== message.origin) {
return false;
}

if (data.indexOf(PostMessageEventNamesEnum.LOADED) > -1) {
PostMessageListener._onLoad(data);
} else if (data.indexOf(PostMessageEventNamesEnum.CUSTOM) > -1) {
Expand Down
2 changes: 2 additions & 0 deletions src/parent.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class Parent {
this.Tab = Tab;
Object.assign(this, config);

tabUtils.config = config;

if (this.shouldInitImmediately) {
this.init();
}
Expand Down
18 changes: 11 additions & 7 deletions src/utils/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import TabStatusEnum from '../enums/TabStatusEnum';
import WarningTextEnum from '../enums/WarningTextEnum';

let tabUtils = {
tabs: []
tabs: [],
config: {}
};

/**
Expand Down Expand Up @@ -84,7 +85,7 @@ tabUtils.getAll = () => {
tabUtils.closeTab = (id) => {
let tab = arrayUtils.searchByKeyName(tabUtils.tabs, 'id', id);

if (tab) {
if (tab && tab.ref) {
tab.ref.close();
tab.status = TabStatusEnum.CLOSE;
}
Expand All @@ -100,9 +101,10 @@ tabUtils.closeAll = () => {
let i;

for (i = 0; i < tabUtils.tabs.length; i++) {
// --tabUtils.tabs.length;
tabUtils.tabs[i].ref.close();
tabUtils.tabs[i].status = TabStatusEnum.CLOSE;
if (tabUtils.tabs[i] && tabUtils.tabs[i].ref) {
tabUtils.tabs[i].ref.close();
tabUtils.tabs[i].status = TabStatusEnum.CLOSE;
}
}

return tabUtils;
Expand Down Expand Up @@ -148,10 +150,12 @@ tabUtils.broadCastTo = (id, msg, isSiteInsideFrame) => {
* @param {Boolean} isSiteInsideFrame
*/
tabUtils.sendMessage = (target, msg, isSiteInsideFrame) => {
let origin = tabUtils.config.origin || '*';

if (isSiteInsideFrame) {
target.ref[0].postMessage(msg, '*');
target.ref[0].postMessage(msg, origin);
} else {
target.ref.top.postMessage(msg, '*');
target.ref.top.postMessage(msg, origin);
}

};
Expand Down

0 comments on commit b630c97

Please sign in to comment.