Is iorad — the tutorial builder safe?

Medium risk

iorad — the tutorial builder is medium risk. Each time iorad starts, it fetches a 470KB config from iorad.com with URL regex patterns controlling which content scripts inject where. The server can change this without a Store update. A compromise or MITM could redirect injection.

iorad.extensionv2.0.0.5731Chrome Web Store
50Risk
Who publishes it

iorad - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
iorad.extension
Declared legal entity
iorad
Registered address
1 Canal St Unit 1119, Boston, MA 02114-2066, US
Registered contact
Sundeep Patel

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

Server-Controlled Content Script Injection Targeting

MediumunwantedCWE-829Dynamic sandbox

Each time iorad starts, it fetches a 470KB config from iorad.com with URL regex patterns controlling which content scripts inject where.

What actually happens

You did this

The extension's background service worker starts and calls requireIntegrations().

This happens automatically on every browser launch or extension reload, before any user interaction.

The extension did this

The iorad server returns a 470 KB JSON payload containing URL regex patterns that tell the extension which content scripts to inject into which tabs.

These patterns take effect immediately and persist until the next restart, no Chrome Web Store update is required to change them.

Captured request

GEThttps://www.iorad.com/api/extensions/configsAndSiteTheme

HTTP 200, 470,662 bytes JSON. Top-level keys include configs[], each entry has an enabled flag and a chromeLazyLoaders array. Each chromeLazyLoaders entry is an array of injection condition objects with url (regex string), topFrame (bool), inactiveTab (bool), plus the module name to inject (e.g. "integrations", "topFrame"). Live example pattern observed: coassemble.com course URLs mapped to the integrations module.

Headers
Accept
application/json, text/plain, */*

The code that does this

Client-side regex compilation and injection dispatch

Readable version

Annotated — what each step does

// 1. Fetch server config (no signature / integrity check)const config = await fetch('https://www.iorad.com/api/extensions/configsAndSiteTheme');const { configs } = await config.json();// 2. For every enabled integration entry in the 470 KB response…for (const integration of configs.filter(c => c.enabled)) {  for (const loaderConditions of integration.chromeLazyLoaders) {    // 3. Server-supplied url string is compiled to a live RegExp — no sanitisation    const conditions = loaderConditions.map(cond => {      if (cond.url && typeof cond.url === 'string') {        cond.url = new RegExp(cond.url); // ← server controls this pattern      }      return cond;    });    // 4. Condition object drives chrome.scripting.executeScript    //    into any tab whose URL matches the server-compiled regex    lazyLoader.require(...conditions); // → executeScript  }}

Fields the server controls in each chromeLazyLoaders entry

  • URL match pattern
    https://coassemble\.com/courses/[^/]+/[^/]+

    A server-supplied regex; compiled client-side, it governs which tabs get the injected script. Changing it redirects injection silently.

  • Module name
    integrations

    Name of the pre-registered content script to inject on a URL match, limited to the 11 bundled modules (e.g. integrations, topFrame, player).

  • Frame targeting
    topFrame: true, inactiveTab: false

    Whether the script targets the top frame or sub-frames, and whether it fires on inactive tabs.

Server that controls injection targeting

    • www.iorad.com

    iorad's production API server. Serves the configsAndSiteTheme endpoint whose response sets which pre-registered scripts inject into which URL patterns, across all installs.

What it can do

Permissions this extension asks for, as declared in version 2.0.0.5731. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on every site you visit

    <all_urls>

  • Store data in your browser

    storage

  • See the address and title of every tab you have open

    tabs

  • Talk to a program installed on your computer, outside the browser's sandbox

    nativeMessaging

  • See every page you navigate to, as you navigate to it

    webNavigation

  • Watch every request your browser makes

    webRequest

  • Store an unlimited amount of data in your browser

    unlimitedStorage

  • Read and change cookies, including the ones that keep you signed in

    cookies

  • Add items to the right-click menu

    contextMenus

  • Run its own code inside the pages you visit

    scripting

  • Run hidden pages in the background

    offscreen

  • Show a panel beside the page

    sidePanel

declarativeNetRequestWithHostAccess
Updated 2 November 2026kjfmedbganalpkohkeghhpppicoigdal