Is Hulu.jp のピクチャー・イン・ピクチャー [QVI] safe?

Low risk

This Hulu.jp picture-in-picture extension also scrapes U-NEXT account and watch history and uploads it to a third-party server.

On any page from the unrelated streaming service U-NEXT (video.unext.jp), a bundled content script checks for an active U-NEXT login and, if found, uses the user's own session cookies to pull account, profile, and full watch/episode history from U-NEXT's API. This data is sent to metricmuse.xyz, a domain unconnected to Hulu.jp or the extension's advertised purpose, which can also issue further data-collection commands back to the extension. The process repeats every 5 minutes while a U-NEXT tab is open.

BestChromeExtensionsv1.0.5Chrome Web Store
22Risk
Who publishes it

HideApp - 38 other listings from the same operator, 1 of them carrying a finding

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

Publisher
BestChromeExtensions
Declared legal entity
HideApp

Shared hosts - 2 hostnames

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.

bestchromextensions.com
Also called by 3 other listings: HBO Max HQ: change video quality [QVI], HBO Max Subtitle Editor RTL Fix, Audio Booster works with Disney+ [QVI]
cc.unext.jp
Also called by 3 other listings: UltraWide for YouTube: custom fullscreen ratios [QVI], NCOverlay, 引用コメントツール

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

Publishers can request a review.

Findings

Bundled module scrapes U-NEXT accounts and watch history to a third-party server

Code analysis shows a bundled module unrelated to this extension's Hulu purpose runs on U-NEXT pages when you're logged in, pulls your account, profile, and watch history via U-NEXT's API, and uploads it to metricmuse.xyz every 5 minutes.

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

You open any page on video.unext.jp while signed into U-NEXT.

U-NEXT is a separate, competing Japanese streaming service; this content script has no role in the extension's Hulu Picture-in-Picture feature.

The extension did this

The extension starts a scrape-and-upload cycle to metricmuse.xyz using your own U-NEXT session.

The cycle repeats on a timer roughly every 5 minutes for as long as a matching tab stays open.

The code that does this

Login-cookie gate and self-rescheduling loop in unext.min.js

Readable version

Readable equivalent

// getCookie() is document.cookie parsing; "_st" is U-NEXT's own login/session cookieconst loggedIn = getCookie("_st");if (!loggedIn) return; // no-op if the visitor isn't signed into U-NEXTconst initData = await fetchCommandsInitData(); // builds the identifying payload// ... POST to metricmuse.xyz, execute returned commands, upload results ...

Readable equivalent

// config_unext_namespaceObject.y6 === 300000 (5 minutes)const rerunTimeInterval = 300000;async function run() {  await scrapeUNext();          // one full fetch-commands + execute + upload cycle  setTimeout(() => run(), rerunTimeInterval); // reschedules itself, no user action needed}
Fields sent to metricmuse.xyz/n/unext/start on every cycle
  • U-NEXT account ID
    accountId=8841203

    Identifies your U-NEXT account specifically, taken from U-NEXT's own GraphQL response.

  • U-NEXT profile ID
    profileId=2291017

    Identifies which profile on the account (U-NEXT supports multiple viewer profiles per account, like family members).

  • Extension user ID
    extensionUserId=6e2a9e2c-9d31-4b7a-8c2e-4f1a0d6b7e21

    A random ID generated once with crypto.randomUUID(), stored in chrome.storage, tying this and future cycles to the same browser.

  • Extension install ID
    dist=bofddckeejglffckncnhcjgahiamcihi

    The extension's own Chrome Web Store install ID (chrome.runtime.id), sent as 'dist'.

  • Country and timezone offset
    country=JP, gmtDiffSeconds=32400

    Coarse location context alongside the account identifiers.

  • Opt-out flag
    optedOut=true

    Reflects the extension's own 'Share insights' settings checkbox, forwarded to the server rather than used locally to skip the scrape.

The code that does this

Watch-history pull uses your own U-NEXT session, filtered by server-supplied field list

Readable version

Readable equivalent

// credentials: 'include' sends the browser's own U-NEXT cookies with the request,// so this call runs as the logged-in victim, not as the extensionconst res = await fetch(  "https://cc.unext.jp/?operationName=cosmo_robustUserInfo&...",  { method: "GET", mode: "cors", credentials: "include", headers });

Readable equivalent

// config.dataFilter is part of the command the C2 server returned, not something// the extension author fixed at build time; it can request any field present in// the merged history + episode + title-metadata objectconst historyFiltered = history.map(item => filterData(item, config.dataFilter));return historyFiltered;
Where the request goes vs. where U-NEXT's own API lives
    • metricmuse.xyz

    Receives the init payload and the filtered U-NEXT account/history data. Not a U-NEXT domain and not referenced in this extension's Hulu feature or listing.

    • cc.unext.jp

    U-NEXT's own GraphQL API, queried with the visitor's real session cookies (credentials:'include') for data that is then forwarded to metricmuse.xyz.

The extension's only visible privacy control does not stop the scrape
  • "Share insights" checkbox (options page)
    shareInsights=false

    The extension's options page has one checkbox, 'Share insights', that writes chrome.storage.sync.shareInsights.

  • How that setting is used
    optedOut is read but not used to gate scrapeUNext()

    scrapeUNext() only checks the login cookie; the stored setting is sent as 'optedOut', never used locally to skip the fetch or upload.

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.5. 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://*/*

  • Store data in your browser

    storage

Where it sends data

Destinations our analysis observed hulujp-%E3%81%AE%E3%83%94%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC%E3%83%BB%E3%82%A4%E3%83%B3%E3%83%BB%E3%83%94%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC 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

    hulujp-%E3%81%AE%E3%83%94%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC%E3%83%BB%E3%82%A4%E3%83%B3%E3%83%BB%E3%83%94%E3%82%AF%E3%83%81%E3%83%A3%E3%83%BC sends data to metricmuse.xyz. 12 other extensions we have analyzed send data here.

Updated 30 September 2026bofddckeejglffckncnhcjgahiamcihi