Cross-origin communication allows different websites to interact with each other. This interaction is typically achieved through mechanisms like AJAX requests, WebSockets, or postMessage API. However, a vulnerability can arise when these communications are not properly secured by verifying their origins.

Why is this an issue?

Without origin verification, the target website cannot distinguish between legitimate requests from its own pages and malicious requests from an attacker’s site. The attacker can craft a malicious website or script that sends requests to a target website where the user is already authenticated.

This vulnerability class is not about a single specific user input or action, but rather a series of actions that lead to an insecure cross-origin communication.

What is the potential impact?

The absence of origin verification during cross-origin communications can lead to serious security issues.

Data Breach

If an attacker can successfully exploit this vulnerability, they may gain unauthorized access to sensitive data. For instance, a user’s personal information, financial details, or other confidential data could be exposed. This not only compromises the user’s privacy but can also lead to identity theft or financial loss.

Unauthorized Actions

An attacker could manipulate the communication between websites to perform actions on behalf of the user without their knowledge. This could range from making unauthorized purchases to changing user settings or even deleting accounts.

How to fix it

When sending a message, avoid using * for the target origin (it means no preference). Instead define it explicitly so the message will only be dispatched to this URI. When receiving the message, verify the orgin to be sure that it is sent by an authorized sender.

Code examples

Noncompliant code example

When sending a message:

var iframe = document.getElementById("testiframe");
iframe.contentWindow.postMessage("hello", "*"); // Noncompliant: * is used

When receiving a message:

window.addEventListener("message", function(event) { // Noncompliant: no checks are done on the origin property.
  console.log(event.data);
 });

Compliant solution

When sending a message:

var iframe = document.getElementById("testiframe");
iframe.contentWindow.postMessage("hello", "https://secure.example.com");

When receiving a message:

window.addEventListener("message", function(event) {
  if (event.origin !== "http://example.org")
    return;

  console.log(event.data)
});

Resources

Documentation

Standards