Is Brisk Teaching - AI that Works Where Teachers Work safe?

Medium risk

Brisk Teaching is medium risk. On every site you visit, content scripts init the Datadog Browser SDK, sending usage events, session IDs, and errors to Datadog US5. URL is blanked, but the session ID and events like "viewed_onboarding_login_page" reach a third party.…

Brisk Teachingv1.0.417Chrome Web Store
45Risk
Who publishes it

Brisk Teaching - no other listings under this identity, 1 shared hostname

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

Publisher
Brisk Teaching
Registered address
3701 Pinewood Bend Ln, Spring, TX 77386-4522, US
Registered contact
Pamela Martinez

Shared hosts - 1 hostname

Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.

wayground.com
Also called by 6 other listings

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

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Brisk Teaching sends usage telemetry to third-party Datadog on every page

On every site you visit, content scripts init the Datadog Browser SDK, sending usage events, session IDs, and errors to Datadog US5.

URL is blanked, but the session ID and events like "viewed_onboarding_login_page" reach a third party.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You visit any website where the extension is active.

Applies to virtually all sites except Cloudflare challenge pages, hCaptcha, Google Meet, and a handful of educational platforms.

The extension did this

The extension initializes the Datadog Browser SDK and transmits usage events and errors to Datadog's US5 infrastructure.

The SDK is initialized with a hardcoded client token; a session ID is assigned and included in every log event sent to the third-party endpoint.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://logs.browser-intake-us5-datadoghq.com/api/v2/logs?ddsource=browser&ddtags=sdk_version%3A4.50.1%2Capi%3Alogs%2Cenv%3Ateacher-prod%2Cservice%3Achrome-extension&dd-api-key=pubd9a36a1f1e06bc7e609e0f5d49d4a79e&dd-evp-origin-version=4.50.1&dd-evp-origin=browser&dd-request-id=37e99d6d-b432-4513-9ddb-78e75615809b
HTTP 202 Accepted
Body
{
  "service": "brisk-fe",
  "session_id": "37e99d6d-b432-4513-9ddb-78e75615809b",
  "view": {
    "url": ""
  },
  "message": "viewed_onboarding_login_page",
  "network": {}
}
03EvidenceFIELD TABLE
Fields transmitted to Datadog per log event
FieldValueWhy it matters
Session ID
37e99d6d-b432-4513-9ddb-78e75615809bA UUID persisting across all tabs where the extension is active, letting Datadog correlate every event in a session to one device.
Event name
viewed_onboarding_login_pageA named action string describing what you did in the extension (e.g. which onboarding step you reached or which feature you used).
Extension version
teacher-prod-1.0.386The installed extension version, included in every request as part of the SDK tag string.
Service name
brisk-feA fixed string identifying the Datadog project receiving the data (brisk-fe). Scopes the events within Datadog's system.
04EvidenceCODE COMPARE
The code that does this

Datadog SDK initialization and beforeSend hook, DatadogHelper.517c2ffb.js:2787

What it actually does
function initDatadog({ env, sampledErrors, service, version }) {
  DD_LOGS.init({
    beforeSend: (event) => {
      const { message } = event;
      const sampleRate = sampledErrors[message] || 1;
      // Drop event based on sampling rate
      if (Math.random() > sampleRate) return false;
      // Suppress page URL and network fields before sending
      event.view = { url: '' };
      event.network = {};
    },
    clientToken: 'pubd9a36a1f1e06bc7e609e0f5d49d4a79e',  // hardcoded public token
    env: env,
    forwardErrorsToLogs: false,
    service: service,
    version: version,
    sessionSampleRate: 100,  // 100% of sessions are tracked
    site: 'us5.datadoghq.com'
  });
}
05EvidenceTHIRD PARTY LIST
Data recipient
  • logs.browser-intake-us5-datadoghq.com

    Datadog US5 log ingestion endpoint, operated by Datadog, Inc. Receives usage events, error messages, session IDs, and extension metadata. Not affiliated with Brisk Learning.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

Brisk Teaching exposes YouTube's internal auth token to any script on the page

On YouTube, Brisk Teaching injects a script into the page JS and overwrites Array.prototype.join to watch YouTube's API traffic, extracting the PoToken verifying sessions, exposed via window.briskYoutubeState.poToken and a <meta> tag.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open a YouTube video or navigate any youtube.com page.

Applies to youtube.com, youtube-nocookie.com, and their subdomains, including embedded players inside other sites, since the content script runs in all frames.

The extension did this

The extension overwrites a built-in JavaScript function so it can copy YouTube's internal session token into a page-readable variable and an off-screen HTML element.

The replacement runs inside the page's own JavaScript environment, not the extension's isolated content-script world, so it is visible to and callable by any other script on the page.

02EvidenceCODE COMPARE
The code that does this

YouTubePoTokenCapture.873fcce4.js, the Array.prototype.join override

What it actually does
!function () {
  const win = window;
  if (win.briskYoutubeState) return;
  const log = (level, msg) => {
    const style = `background: ${level === "info" ? "blue" : "red"}; color: white`;
    console.log("%cYT%c", style, "", msg);
  };
  const state = { arrayJoinOverride: false, poToken: null, updatedAt: null };
  log("info", "injection started");
  win.briskYoutubeState = state;
  try {
    const originalJoin = Array.prototype.join;
    Array.prototype.join = function (...args) {
      const isPotcCall = args.length === 1 && args[0] === "&" && this.includes("potc=1");
      if (isPotcCall) {
        (function extractToken(parts) {
          const potPart = parts.find((p) => typeof p === "string" && p.startsWith("pot="));
          if (typeof potPart !== "string") return;
          const raw = potPart.split("=")[1];
          if (!raw) return;
          const token = decodeURIComponent(raw);
          const changed = state.poToken !== token;
          state.poToken = token;
          state.updatedAt = new Date().toLocaleString();
          const meta = document.getElementById("brisk-yt-po-token") || document.createElement("meta");
          meta.id = "brisk-yt-po-token";
          meta.setAttribute("name", "brisk-yt-po-token");
          meta.setAttribute("content", token);
          if (!meta.parentNode) document.head.appendChild(meta);
          log("info", changed ? `Token + "${token.substring(0, 20)}..."` : `Token = "${token.substring(0, 20)}..."`);
        })(this);
      }
      return originalJoin.apply(this, args);
    };
    state.arrayJoinOverride = true;
    log("info", "injection completed");
  } catch (err) {
    log("error", err instanceof Error ? err.message : String(err));
  }
}();
03EvidenceDOM DIFF
Page DOM modified

Target: The <head> element of any open youtube.com tab

A <meta> element carrying the captured PoToken is appended to <head> the first time the override fires, then updated in place (same element, new content attribute) on every later capture.

Before
<head>
  <!-- YouTube's own <head> elements: <title>, <link rel="canonical">, meta tags, etc. -->
</head>
After (modified by extension)
<head>
  <!-- YouTube's own <head> elements unchanged -->
  <meta id="brisk-yt-po-token" name="brisk-yt-po-token" content="<redacted>">
</head>
04EvidenceFIELD TABLE
What ends up readable by any script on the YouTube page
FieldValueWhy it matters
Captured session token (JS variable)
window.briskYoutubeState.poToken = "<redacted>"YouTube's own token for proving your browser session is legitimate, copied into a plain global variable any script on the page can read.
Captured session token (DOM)
<meta id="brisk-yt-po-token" content="<redacted>">The same token, also placed in a page element, so it can be read without even touching JavaScript globals, e.g. via document.querySelector.
Override status flag
window.briskYoutubeState.arrayJoinOverride = trueA flag confirming the prototype override installed successfully, also readable by any page script.
Last capture time
8/29/2026, 4:12:03 PM (illustrative)A local timestamp recorded every time a new token is captured, letting any reader know how fresh the exposed token is.
05EvidenceARTIFACT
Check if you're affected

Paste into the DevTools console on a youtube.com tab to check whether the extension's Array.prototype.join override is active and whether it has exposed a PoToken to the page.

RequiresA Chromium-based browserBrisk Teaching extension installed and enabledA youtube.com tab with a video loaded
check-brisk-yt-token-exposure.js · js
(function () {
  const isOverridden = !Array.prototype.join.toString().includes("[native code]");
  const state = window.briskYoutubeState;
  const metaTag = document.getElementById("brisk-yt-po-token");
  console.log("Array.prototype.join overridden:", isOverridden);
  console.log("window.briskYoutubeState:", state);
  console.log("PoToken meta tag present:", !!metaTag);
  if (metaTag) {
    console.log("Meta tag content length:", metaTag.getAttribute("content").length);
  }
})();
How to run it
  1. 1
    Open youtube.com, let a video load.
  2. 2
    Open DevTools, Console tab.
  3. 3
    Paste the script, press Enter.
  4. 4
    If 'join overridden' logs true and a PoToken meta tag is present, the token is exposed to the page's global scope.
Updated 30 September 2026pcblbflgdkdfdjpjifeppkljdnaekohj