Is Netflix Speeder: adjust playback speed [QVI] safe?
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.
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
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 open or use Netflix with the extension installed.
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 IDaccountId=7425819361048290 (illustrative)
This ties activity to the Netflix account context available in the page.
- Netflix profile IDprofileId=72f4419b-0f2d-4d6b-8a25-0a8a2f4b7d64 (illustrative)
This separates which Netflix profile was active when the extension ran.
- Extension user IDextensionUserId=0a63b94a-b48e-4371-9ef7-3e531f85cf3a (illustrative)
This lets repeated requests from the same browser profile be linked over time.
- Country and languagecountry=US; browserLanguage=en-US (illustrative)
This adds location and locale context to the Netflix profile data.
- Sharing preferenceshareInsights=false; optedOut=true (illustrative)
This records whether the browser had sharing disabled, but the same code path still proceeds.
- Netflix account fieldsmodels.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
The code parses a JSON response containing commands for the Netflix flow; verification did not store a request or response body for this claim.
- Content-Type
- application/json
Captured request
Verification evidence recorded dlog POSTs to this endpoint; no request body was stored with the claim evidence.
- Content-Type
- application/json
The code that does this
The default-on setting is read, then serialized into the server-bound init object
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.jsvar 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.jsvar 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 counterpart: JSON POST helper
netflix.beauty.jsvar 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.jsvar 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.jsvar 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.