Front end communication

As mentioned before every plug-in instance is embedded into COYO via an HTML iFrame. To safely communicate between the parent site (i.e. the COYO 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 COYO 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, COYO 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 COYO 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 COYO. While COYO 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 COYO 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.

MDN web docs

COYO 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 the origin field in your plugin manifest.

However, while COYO 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 COYO 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 the targetOrigin when sending messages to the COYO 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. COYO automatically generates a unique random UUID and attach it to the URL as a src query parameter. The src 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 COYO to the plug-in, COYO will not send plain JSON data in response events. Instead, every COYO 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 COYO 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.


Did this page help you?