Is Magic Actions for YouTube™ safe?

Medium risk

Enhances YouTube watching with AutoHD, cinema mode, playback controls, and visual customization.

This extension adds YouTube viewing features such as automatic HD playback, mouse-wheel volume control, cinema shading, day/night mode, wide player mode, replay, and options to hide annotations, comments, and related videos. It can take snapshots from playing videos, enlarge avatars and thumbnails on hover, manage autoplay and preloading, and provide a skip button for some ads. If enabled, its AI-based reminders analyze the system and occasionally show notices about bug fixes, account security impact, and media performance.

www.hotcleaner.comv7.9.5.6Chrome Web Store
49Risk

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

Publishers can request a review.

Findings

Recurring fingerprint beacon to api64.com with persistent user ID

The service worker builds a fingerprint (browser, timezone, language, click count, settings), POSTs it to api64.com/upd7 on install and ~5hr intervals.

A random ID links sessions.

A time-bucket guard blocked the call in DA; code ships.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You install the extension or restart your browser.

No interaction is needed, the beacon fires automatically on startup.

The extension did this

The service worker sends a fingerprint JSON POST to api64.com/upd7, including a persistent UUID tied to your installation.

The same UUID is sent on every subsequent call, allowing cross-session tracking.

When this fires

Every 5 hours

nb() checks whether the current 18 000-second bucket (≈5 hours) differs from the stored e.uf value; if so, Aa() is called and e.uf is updated. On first install the bucket is always 0, guaranteeing an immediate call.

Fields transmitted to api64.com/upd7
  • Persistent user ID (d)
    a3f2c891-4b1e-4f3a-82d0-c7e9f1234567

    A UUID generated on first install and persisted in chrome.storage.local; ties every beacon to the same user across browser sessions.

  • Browser name (f)
    Google Chrome

    Identifies which browser you are using (e.g. Google Chrome, Brave, Microsoft Edge).

  • Browser version (g, j, k, n)
    128.0.6613.137

    Full version number broken into four components, reported for both the named browser and the underlying Chromium build.

  • Timezone offset (o)
    -5

    Your UTC offset in hours, used to narrow geographic location.

  • Language (p)
    en-US

    Your browser's preferred language setting.

  • Minutes since install (c)
    4320

    How long the extension has been installed on this device; distinguishes new from long-term users.

  • Menu-click counter (r)
    17

    Number of times the extension's menu has been opened; measures engagement over time.

The code that does this

Fingerprint collection and POST, esw30.js lines 131-214

Readable version
// lb() — collects browser fingerprintlb = async function() {  let versionToArray = v => {    let parts = [0, 0, 0, 0];    v = typeof v === 'string' && v.split('.') || [];    for (let i = 0; i < v.length; i++) {      let n = parseInt(v[i]);      if (!isNaN(n)) parts[i] = n;    }    return parts;  };  if ('userAgentData' in navigator) {    let uad = navigator.userAgentData;    if (uad.getHighEntropyValues)      uad = await uad.getHighEntropyValues(['fullVersionList']);    let chromiumVersion, browserVersion;    let browserIndex = 0;    const KNOWN_BROWSERS = 'Google Chrome;Microsoft Edge;Opera;Opera GX;Opera Crypto;Yandex;Brave'.split(';');    const brands = uad.fullVersionList || uad.brands || [];    for (const entry of brands) {      const brand = entry.brand;      for (let i = 0; i < KNOWN_BROWSERS.length; i++) {        if (brand === KNOWN_BROWSERS[i]) {          browserIndex = i + 1;          browserVersion = entry.version;          e.bn = KNOWN_BROWSERS[i];  // store browser name in state          break;        }      }      if (brand === 'Chromium') chromiumVersion = entry.version;    }    const platform = getPlatformCode(uad.platform || '');    return [browserIndex, versionToArray(browserVersion),            platform === 'w' ? 1 : platform === 'm' ? 2 : platform === 'c' ? 3 : platform === 'l' ? 4 : 0,            versionToArray(chromiumVersion)];  }  return [0, [0,0,0,0], '', [0,0,0,0]];};// Aa() — builds and POSTs the fingerprint beaconAa = async function(extra) {  let result;  try {    const [browserIdx, browserVer, platformCode, chromiumVer] = await lb();    const now = Date.now();    const minutesSinceInstall = Math.floor((now - (e.ai || 0)) / 60000);    const minutesSinceLastDialog = Math.floor((now - (e.md || 0)) / 60000);    const payload = {      a: 7,              // protocol version      b: 7956,           // product code      c: minutesSinceInstall,      d: e.au,           // persistent user ID      e: platformCode,      f: browserIdx,      g: browserVer[0], h: browserVer[1], i: browserVer[2], j: browserVer[3],      k: chromiumVer[0], l: chromiumVer[1], m: chromiumVer[2], n: chromiumVer[3],      o: new Date().getTimezoneOffset() / 60,      p: navigator.language || '',      r: e.mc || 0,      // menu-click counter      s: minutesSinceLastDialog,      t: e.ma || 0,      // setting: ma      u: e.me ? 1 : 0,  // setting: me      w: e.mt || 0,      // setting: mt      y: e.ms || 0,      // setting: ms      z: e.ml || 0       // setting: ml    };    if (extra) for (let k in extra) payload[k] = extra[k];    const [response, status] = await fetch('https://api64.com/upd7', {      method: 'POST', cache: 'no-store',      body: JSON.stringify(payload),      headers: { 'Content-Type': 'application/json' }    }, 'json');    if (status === 0) await applyServerSettings(response);    result = status || response;  } catch (err) { logError(err); result = 5; }  return result;};// nb() — timer scheduler; fires Aa() once per ~5-hour bucketnb = function() {  let elapsed = Date.now() - EPOCH_OFFSET;  let bucket = elapsed < 18000000 ? 0 : Math.floor(elapsed / 18000000);  if (e.uf !== bucket) { e.uf = bucket; Aa(null); }};
Network destination
    • api64.com

    Receives the fingerprint beacon POST at /upd7; may return settings fields that the extension applies locally. Domain is not disclosed in the extension's Chrome Web Store listing.

Extension makes redundant update check with cookies included

On startup, with broad host permissions, this extension GETs Google's update endpoint (clients2.google.com/service/update2/crx), apart from Chrome's own check.

URL carries ID/version; credentials include cookies; retries 3x.

DA captured it.

Severity
Low unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You start your browser and the extension loads.

The behavior requires that the extension holds broad host permissions (https://*/*), which Magic Actions for YouTube requests in its manifest.

The extension did this

The service worker fetches Google's CRX update endpoint, sending your extension ID and version in the URL with cookies included.

This fetch is made by the extension's own code, separate from Chrome's built-in automatic update mechanism which already contacts this endpoint independently.

Captured request
GEThttps://clients2.google.com/service/update2/crx?x=id%3Dabjcfabbhafbcdfjoecdgepllmpfceif%26v%3D7.9.5.6%26uc

HTTP 200. Response content is not read by the extension (response text is discarded).

The code that does this

The function that makes the update-endpoint request, from esw30.js.

Readable version
// Fetches the Chrome CRX update endpoint from the service worker.// Called on startup when the extension has broad host permissions.// `a` is the attempt counter (0-2); retries up to 3 times on error.function fetchUpdateEndpoint(attempt) {  if (attempt >= 3) return; // max 3 attempts  fetch(    'https://clients2.google.com/service/update2/crx' +    '?x=id%3Dabjcfabbhafbcdfjoecdgepllmpfceif%26v%3D7.9.5.6%26uc',    {      method: 'GET',      cache: 'no-store',      credentials: 'include',  // attaches any cookies for this domain      redirect: 'manual'    }  ).then(([_body, errorCode]) => {    if (errorCode > 1) {      // Non-success: schedule a retry after 3.3 seconds      setTimeout(fetchUpdateEndpoint, 3300, attempt + 1);    }    // On success (errorCode === 0), the response text is discarded  });}
Why this is notable

Chrome already contacts `clients2.google.com/service/update2/crx` automatically to check for extension updates — this is a built-in browser function. What makes this request distinct is that it is issued by the extension's own service worker JavaScript code, separately from the browser's built-in mechanism, and it uses `credentials:'include'`.

The `credentials:'include'` flag tells the browser to attach any cookies it holds for `clients2.google.com` to the outbound request. Whether Google sets such cookies and what they contain depends on whether you are signed into a Google account in that browser profile. The extension does not read or forward the server's response — the response body is discarded.

This is a low-severity finding because the destination is Google's own infrastructure, the request carries only the extension ID and version (both public information), and the response is unused. The `credentials:'include'` flag is nonetheless an unusual choice for what is described as an update check.

What it can do

Permissions this extension asks for, as declared in version 7.9.5.6. 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

    http://*/*

  • Read and change your data on every secure site you visit

    https://*/*

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

    tabs

  • Add items to the right-click menu

    contextMenus

  • Store data in your browser

    storage

  • Run its own code inside the pages you visit

    scripting

Where it sends data

Destinations our analysis observed Magic Actions for YouTube contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • chromeactions.com

    Magic Actions for YouTube sends data to chromeactions.com. No other extension we have analysed sends data here.

Updated 21 September 2026abjcfabbhafbcdfjoecdgepllmpfceif