
Research
Security News
Lazarus Strikes npm Again with New Wave of Malicious Packages
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Framebus allows you to easily send messages across frames (and iframes) with a simple bus.
Framebus is a lightweight JavaScript library for cross-frame communication. It allows you to send and receive messages between different browsing contexts, such as iframes, windows, or tabs, using a simple event-based API.
Publishing Events
This feature allows you to publish events to other frames. The `emit` method sends an event with a specified name and data payload to any listeners in other frames.
const framebus = require('framebus');
framebus.emit('eventName', { key: 'value' });
Subscribing to Events
This feature allows you to subscribe to events from other frames. The `on` method listens for an event with a specified name and executes a callback function when the event is received.
const framebus = require('framebus');
framebus.on('eventName', (data) => {
console.log(data); // { key: 'value' }
});
Unsubscribing from Events
This feature allows you to unsubscribe from events. The `off` method removes a previously registered event listener, preventing the callback from being executed when the event is emitted.
const framebus = require('framebus');
const callback = (data) => {
console.log(data);
};
framebus.on('eventName', callback);
// Later, to unsubscribe
framebus.off('eventName', callback);
Post-robot is a library for cross-domain iframe communication. It provides a robust API for sending and receiving messages between different windows or iframes, with support for promises and error handling. Compared to framebus, post-robot offers more advanced features like message validation and security checks.
JSChannel is a library for secure cross-domain communication between iframes. It uses a message-passing mechanism to enable communication between different browsing contexts. Compared to framebus, JSChannel focuses more on security and provides a structured protocol for message exchange.
Crossmessaging is a library for cross-origin communication between iframes and windows. It provides a simple API for sending and receiving messages, similar to framebus. However, crossmessaging includes additional features like message queuing and retry mechanisms.
Framebus allows you to easily send messages across frames (and iframes) with a simple bus.
In one frame:
var Framebus = require("framebus");
var bus = new Framebus();
bus.emit("message", {
from: "Ron",
contents: "they named it...San Diago",
});
In another frame:
var Framebus = require("framebus");
var bus = new Framebus();
bus.on("message", function (data) {
console.log(data.from + " said: " + data.contents);
});
The Framebus class takes a configuration object, where all the params are optional.
type FramebusOptions = {
origin?: string, // default: "*"
channel?: string, // no default
verifyDomain?: (url: string) => boolean, // no default
targetFrames?: <HTMLFrameElement | Window>[], // by default, all frames available to broadcast to
};
The origin
sets the framebus instance to only operate on the chosen
origin.
The channel
namespaces the events called with on
and emit
so you
can have multiple bus instances on the page and have them only
communicate with busses with the same channel value.
If a verifyDomain
function is passed, then the on
listener will only
fire if the domain of the origin of the post message matches the
location.href
value of page or the function passed for verifyDomain
returns true
.
var bus = new Framebus({
verifyDomain: function (url) {
// only return true if the domain of the url matches exactly
url.indexOf("https://my-domain") === 0;
},
});
If a targetFrames
array is passed, then framebus will only send
messages to those frames and listen for messages from those frames. You
can pass a reference to a Window
(the return value of window.open
)
or an HTMLFrameElement
(a DOM node representing an iframe).
var myIframe = document.getElementById("my-iframe");
var bus = new Framebus({
targetFrames: [myIframe],
});
To add additional frames to the targetFrames
array in the future, use
the addTargetFrame
method. targetFrames
must be set, even if it's an
empty array, for this method to work.
var myIframe = document.getElementById("my-iframe");
var bus = new Framebus({
targetFrames: [],
});
bus.addTargetFrame(myIframe);
target(options: FramebusOptions): framebus
returns: a chainable instance of framebus that operates on the chosen origin.
This method is used in conjuction with emit
, on
, and off
to
restrict their results to the given origin. By default, an origin of
'*'
is used.
framebus
.target({
origin: "https://example.com",
})
.on("my cool event", function () {});
// will ignore all incoming 'my cool event' NOT from 'https://example.com'
Argument | Type | Description |
---|---|---|
options | FramebusOptions | See above section for more details |
emit('event', data?, callback?): boolean
returns: true
if the event was successfully published, false
otherwise
Argument | Type | Description |
---|---|---|
event | String | The name of the event |
data | Object | The data to give to subscribers |
callback(data) | Function | Give subscribers a function for easy, direct replies |
emitAsPromise('event', data?): Promise
returns: A promise that resolves when the emitted event is responded to the first time. It will reject if the event could not be succesfully published.
Argument | Type | Description |
---|---|---|
event | String | The name of the event |
data | Object | The data to give to subscribers |
Using this method assumes the browser context you are using supports
Promises. If it does not, set a polyfill for the Framebus class with
setPromise
// or however you want to polyfill the promise
const PolyfilledPromise = require("promise-polyfill");
Framebus.setPromise(PolyfilledPromise);
on('event', fn): boolean
returns: true
if the subscriber was successfully added, false
otherwise
Unless already bound to a scope, the listener will be executed with
this
set to the MessageEvent
received over
postMessage.
Argument | Type | Description |
---|---|---|
event | String | The name of the event |
fn(data?, callback?) | Function | Event handler. Arguments are from the emit invocation |
↳ this | scope | The MessageEvent object from the underlying postMessage |
off('event', fn): boolean
returns: true
if the subscriber was successfully removed, false
otherwise
Argument | Type | Description |
---|---|---|
event | String | The name of the event |
fn | Function | The function that was subscribed |
include(popup): boolean
returns: true
if the popup was successfully included, false
otherwise
var popup = window.open("https://example.com");
framebus.include(popup);
framebus.emit("hello popup and friends!");
Argument | Type | Description |
---|---|---|
popup | Window | The popup refrence returned by window.open |
addTargetFrame(frame): boolean
Used in conjunction with targetFrames
configuration. If a
targetFrames
array is not passed on instantiation, this method will
noop.
var frame = document.getElementById("my-iframe");
framebus.addTargetFrame(frame);
framebus.emit("hello targetted iframe!");
Argument | Type | Description |
---|---|---|
frame | Window or HTMLIFrameElement | The iframe or popup to add to targetFrames |
teardown(): void
Calls off
on all listeners used for this bus instance and makes
subsequent calls to all methods noop
.
bus.on("event-name", handler);
// event-name listener is torn down
bus.teardown();
// these now do nothing
bus.on("event-name", handler);
bus.emit("event-name", data);
bus.off("event-name", handler);
These are some things to keep in mind while using framebus to handle your event delegation
framebus allows convenient event delegation across iframe borders.
By default it will broadcast events to all iframes on the page,
regardless of origin. Use the optional target()
method when you know
the exact domain of the iframes you are communicating with. This will
protect your event data from malicious domains.
framebus operates over postMessage
using JSON.parse
and
JSON.stringify
to facilitate message data passing. Keep in mind that
not all JavaScript objects serialize cleanly into and out of JSON, such
as undefined
.
Even when the subscriber and publisher are within the same frame, events
go through postMessage
. Keep in mind that postMessage
is an
asynchronous protocol and that publication and subscription handling
occur on separate iterations of the event loop
(MDN).
When you specify a callback
while using emit
, the function is not
actually given to the subscriber. The subscriber receives a one-time-use
function that is generated locally by the subscriber's framebus.
This one-time-use callback function is pre-configured to publish an
event back to the event origin's domain using a
UUID as the event name. The events
occur as follows:
http://emitter.example.com
publishes an event with a function as
the event data
var callback = function (data) {
console.log("Got back %s as a reply!", data);
};
framebus.emit("Marco!", callback, "http://listener.example.com");
The framebus on http://emitter.example.com
generates a UUID as
an event name and adds the callback
as a subscriber to this event.
The framebus on http://listener.example.com
sees that a
special callback event is in the event payload. A one-time-use
function is created locally and given to subscribers of 'Marco!'
as the event data.
The subscriber on http://listener.example.com
uses the local
one-time-use callback function to send data back to the emitter's
origin
framebus
.target("http://emitter.example.com")
.on("Marco!", function (callback) {
callback("Polo!");
});
The one-time-use function on http://listener.example.com
publishes
an event as the UUID generated in step 2 to the origin that
emitted the event.
Back on http://emitter.example.com
, the callback
is called and
unsubscribed from the special UUID event afterward.
See CONTRIBUTING.md
6.0.3
FAQs
Framebus allows you to easily send messages across frames (and iframes) with a simple bus.
The npm package framebus receives a total of 253,795 weekly downloads. As such, framebus popularity was classified as popular.
We found that framebus demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.
Security News
Opengrep continues building momentum with the alpha release of its Playground tool, demonstrating the project's rapid evolution just two months after its initial launch.