Front end communication
As mentioned before every plug-in instance is embedded into Haiilo Home via an HTML iFrame. To safely communicate between the parent site (i.e. the Haiilo Home front end) and the iFrame embedded within it, you can use the window.postMessage()
method. Usually, scripts on different pages are allowed to access each other if and only if the pages they originate from share the same protocol, port number, and host (also known as the "same-origin policy"). window.postMessage()
provides a controlled mechanism to securely circumvent this restriction (if used properly).
The receiver (both the plug-in as well as Haiilo Home itself) can listen for dispatched messages by registering a global message
event listener.
Data format
While the data sent via window.postMessage()
can be an arbitrary JavaScript object, Haiilo Home will only accept messages in a specific format that derives from RFC 7519 - JSON Web Token. It is important to adhere to this data format in order to successfully establish a communication to the Haiilo Home front end. Every message must thus incorporate the following properties:
Attribute | Type | Description |
---|---|---|
iss | string | The issuer of the message - a unique identifier of the principal that issued the JWT. |
sub | string | The subject of the message - one of several predefined topics that is the subject of the JWT. |
jti | string | A random nonce unique identifier for the JWT that is used to prevent the JWT from being replayed. |
A message can hold additional payload on arbitrary attributes that don’t collide with the claim names above. Any message that does not comply with this format will be rejected by Haiilo Home. While Haiilo Home uses the current tenant’s URL for the issuer claim, a plug-in is provided with a unique source string in the invocation URL. This URL query parameter called src
is to be used for the issuer claim so that Haiilo Home is able to identify the plug-in.
Secure communication
To secure the communication across different pages one should always specify the targetOrigin
in a window.postMessage()
call and the origin
of the window that sent a message received via window.addEventListener
.
Any window may access this method on any other window, at any time, regardless of the location of the document in the window, to send it a message. Consequently, any event listener used to receive messages must first check the identity of the sender of the message, using the origin and possibly source properties. This cannot be overstated: Failure to check the origin and possibly source properties enables cross-site scripting attacks.
Haiilo Home will only sent messages to the URL defined in the plug-in manifest and will double check any received messages for this URL. This is to make sure that every message sent and received belongs to the respective plug-in.
Hint
If you are using a middleware for your plugin, you can specify alternative
targetOrigins
using theorigin
field in your plugin manifest.
However, while Haiilo Home exactly knows where to find a plug-in via its accompanying manifest, the plug-in itself is in a slightly more difficult situation. Since every plug-in can be installed in a variety of different Haiilo Home environments (each one hosted under a different URL), it is hard to specify the targetOrigin
for outgoing messages and check for the origin
of incoming messages. This has a bunch of implications:
-
The plug-in needs to set the literal string
"*"
as thetargetOrigin
when sending messages to the Haiilo Home front end. Consequently, the plug-in cannot be fully certain that events are not disclosed to a malicious site. Thus, no highly confidential data must be sent this way. Instead, you might want to fall back to a back end to back end communication. -
The plug-in must set the
iss
claim of the message to the unique identifier that is passed to the plug-in via the invocation URL. Haiilo Home automatically generates a unique random UUID and attach it to the URL as asrc
query parameter. Thesrc
property will not change over the lifetime of the plugin instance. -
The plug-in is not able to check the origin of the event within callbacks of
window.addEventListener
. After all, the plug-in does not know where it is embedded. To establish a trustworthy communication from Haiilo Home to the plug-in, Haiilo Home will not send plain JSON data in response events. Instead, every Haiilo Home message is sent as a signed JSON Web Token. JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. You can read more about JWT and possible ways to decode a JWT at jwt.io.
Avoiding replay attacks
To prevent replay attacks, you should add a nonce to every message sent via the window.postMessage()
API using the jti
claim in outgoing messages. The definition of a nonce is optional, but Haiilo Home will place a randomly generated UUID in every message if a user-defined nonce is missing.
Hint
You can also use the
jti
claim to add unique message IDs to your communication and thus allow for an unambiguous correlation between requests sent and responses received.
Updated over 2 years ago