Flash Player 2026: Server-Configured Page Injection
ModernKit’s Flash extensions could retarget bundled scripts and extract matching XHR responses. The April 2026 test observed an empty target configuration.
Flash Player Emulator 2026 bundled the Ruffle Flash emulator alongside code that fetched page-targeting instructions from ModernKit's servers. The package could register scripts on selected sites and extract fields from matching XHR responses.
That capability was present in the reviewed code. During the live test on 16 April 2026, the server returned an empty target configuration. The investigation did not observe an active target list or establish which sites had previously been targeted.
The Chrome extension ID is ecbnojockcgfohpopbphhgefkfbigcej; the Edge ID is fgenmmklgkdemhpgdppmldmkemplbcko. Install figures in this report describe the April investigation.
Configuration controls the targets
The relevant files were bg.js, detection-alternate.js and detection-alternate-init.js. On an hourly alarm, the background code requested features:
POST https://api.modernkit.one/ext-activations/get-features
{ "app": "ext-flashplayer", "uuid": "<persistent-device-uuid>", "version": "1.9.3" }
The alternateDetectionConfigv2 response supplied entries with base64-encoded hostnames. The client decoded them into match patterns and registered two bundled scripts:
const hostsToAdd = [];
for (const alternateConfig of data.alternateDetectionConfigv2) {
const host = atob(alternateConfig.host);
hostsToAdd.push('https://*.' + host + '/*');
}
chrome.scripting.registerContentScripts([
{
id: 'alternate_detection',
matches: hostsToAdd,
js: ['detection-alternate.js'],
world: 'MAIN',
runAt: 'document_start'
},
{
id: 'alternate_detection_init',
matches: hostsToAdd,
js: ['detection-alternate-init.js'],
world: 'ISOLATED',
runAt: 'document_start'
}
]);
The isolated bootstrap sent a message to the background process, which invoked mk1StartAlternateDetection() in the page context with the supplied configuration. Base64 made the target values less readable; it did not encrypt them.
The publisher could change the target list through its API without shipping another extension version, subject to the extension's granted host access. Reviewing only the initial static match list would miss that behaviour.
Response interception
detection-alternate.js replaced the page's XHR open method. The following excerpt shows the matching logic; comments stand in for the extraction code:
var mk1CheckPath = atob(mk1AlternateConfig.path);
var mk1CheckBody = atob(mk1AlternateConfig.body);
var mk1OriginalXHROpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, isAsync) {
if (url.indexOf(mk1CheckPath) > -1) {
this.addEventListener('load', () => {
if (this.responseText.indexOf(mk1CheckBody) > -1) {
// parse response body using server-provided key paths
// filter using server-provided excludeKeys list
// send to exfiltration iframe
}
});
}
return mk1OriginalXHROpen.apply(this, arguments);
};
Configuration selected the URL path and body marker. The extraction code used configured key paths and exclusions, then passed the result through the hidden mk1PageBridge iframe to api-det.modernkit.one/alternate-detection/process-detection.
The script ran in the page's MAIN world. It could alter the XHR API and inspect responses handled by that hook. That does not mean it could read every value held in JavaScript memory: lexical scope and the application's own implementation still matter.
The manifest's static exclude_matches entries included banking and authentication sites. Those exclusions applied to their declared content scripts. They did not automatically constrain the separately registered scripts shown above. The code demonstrates that gap; it does not establish why the publisher chose the static exclusions.
Shared files across stores
The original comparison recorded matching hashes for the relevant Chrome and Edge files:
bg.js (Chrome): 84b585e73b507c64e959ba5bcecf2cdba7e68e86...
bg.js (Edge): 84b585e73b507c64e959ba5bcecf2cdba7e68e86...
detection-alternate.js (Chrome): b03d54ef53614f647e2b3d54c2daca37918bdc84...
detection-alternate.js (Edge): b03d54ef53614f647e2b3d54c2daca37918bdc84...
These displayed values are truncated hash prefixes from the recorded file comparison. They cannot establish that every byte of both store packages was identical. The Chrome listing had over 200,000 installs and Edge over 360,000. Both used [email protected] and the same API infrastructure.
Two other packages in the publisher portfolio raised separate questions. Keyboard & Mouse for Xbox Cloud Gaming, ID nmfedkijhhigaikbadoijiolmjjgoimd, had over 200,000 installs and requested configuration through:
POST https://api.modernkit.one/ext-activations-xkbm/get-config
{ "app": "ext-xkbm", "uuid": "<device-uuid>", "version": "..." }
That shared endpoint pattern does not prove it received the Flash extension's injection configuration.
Old Layout for Facebook, ID abmkkackbbimmdbfjdilpnfaegaeagge, had over 100,000 installs. Its content script extracted a Facebook token and user ID:
dtsg = document.body.textContent.match(/"DTSGInitialData".*?"token":"(.*?)"/)[1];
c_user = document.cookie.match(/c_user=([0-9]+)/)[1];
The reviewed code used their presence to trigger applyTheme; the message did not include the extracted values. The review did not identify their transmission. Their role deserves an explanation, but speculation about a later payload would exceed this observation.
Together the four listings had over 860,000 installs. The investigation did not measure how many users were affected by collection.
What the test established
The April test used Chromium, a residential connection and the real extension ID. The extension called get-features on install and on its timer. The observed response contained alternateDetectionConfigv2: {}.
Static inspection established a configurable extraction path. The observation window did not establish active collection through it. Historical targeting would require captured configurations or server records that this report does not have.
Our original automated review treated the ModernKit domain finding as a likely false positive. The more useful review considers how remote targets reach registerContentScripts() and how the resulting script hooks XHR. Each API has legitimate uses; their data flow is what requires explanation.
The original report recorded a disclosure to Microsoft and a planned Google submission. This revision does not claim a later response or enforcement outcome.
Investigating an installed copy
Match the installed version and artifact before applying this report's conclusions. Administrators can use the extension IDs above and the domains modernkit.one, api.modernkit.one and api-det.modernkit.one as investigation leads. A domain match alone is insufficient to establish data theft.
Full scorecards and findings for all four ModernKit.one extensions are on the platform:
- Flash Player Emulator 2026 (Chrome)
- Flash Player 2026 (Edge)
- Keyboard & Mouse for Xbox Cloud Gaming (Chrome)
- Old Layout for Facebook (Chrome)
A review of this design needs both the bundled code and the configuration it receives. Retaining those responses alongside the artifact would make future assessments more conclusive.