Remote HTML Injection through Browser Extensions
Introduction
Browser extensions often display notifications, tips, or promotional banners. A common-but risky-implementation is fetching HTML from a remote server and inserting it directly into the extension UI using innerHTML. This creates a remote-controlled content channel: whoever controls the server can change what users see at any time, without publishing a new extension version.
The pattern (what we observed)
A set of extensions from the same publisher used a similar approach: -Fetch a JSON payload from a remote domain -Read the HTML field from the response -Inject it into the DOM using innerHTML -Use localStorage to decide when to show “new” content (based on a server-provided timestamp)
/// popup.js
fetch("https://api.gameograf.com/popup/message.json")
.then(r => r.json()) // { html: "...", timestamp: ... }
.then(({ html, timestamp }) => {
const lastShown = parseInt(localStorage.getItem("popupLastShown") || "0");
if (timestamp > lastShown) {
popupContainer.innerHTML = html; // unsanitized injection
localStorage.setItem("popupLastShown", String(timestamp));
}
});
fetched JSON file content
/// message.json (Present JSON content)
{
"html": "<div><strong>🎨 New Feature! Create Your Own Chrome Theme</strong><br>Upload your favorite photo and generate your personalized theme instantly.<br><a href='https://gameograf.com/?utm_source=themespopup&utm_medium=themespopup'>Create My Theme</a></div>",
"timestamp": 1769539200000
}
How the “remote switch” works
On load, the extension compares the remote timestamp with a locally stored value (e.g., popupLastShown). If the remote timestamp is newer, it renders the remote HTML and updates popupLastShown. This timestamp check effectively acts like a server-controlled “content version”:
- If the server keeps the same timestamp, most users won’t see the popup again.
- If the server bumps the timestamp, users who open/load the extension UI will see the new content again.
- The extension package does not change, but the UI content does.
Present permissions
| Manifest field | Value | What it enables |
|---|---|---|
permissions |
["search"] |
Access to Chrome’s Search API-related extension features |
host_permissions |
["https://api.gameograf.com/*"] |
host_permissions for https://api.gameograf.com/* enables the extension’s remote messaging channel (the JSON endpoint that supplies the HTML). |
Why this matters (security impact in plain terms)
Even if the extension code is “static,” the remote endpoint becomes a dynamic control plane. That introduces a supply-chain style risk:
- The publisher can change user-facing UI at any time by editing server-side content.
- An attacker who compromises the server gains the same ability.
- Users do not need to install an update to be exposed to new (and potentially malicious) messaging.
- The Chrome Web Store review process is effectively bypassed for content changes because the HTML is delivered after installation.
This is not “evading Chrome security” via a vulnerability in Chrome itself. It’s a design choice that shifts trust from the packaged extension to a remotely controlled endpoint.
Threat model: what can go wrong without JavaScript execution
A common objection is: “Manifest V3 has CSP, so scripts won’t run.” Even if JavaScript execution is restricted, phishing and UI deception often don’t require script. Remote HTML injected into a highly trusted surface (like an extension’s New Tab page) can still drive harmful outcomes
Remote change = remote behavior change (what users experience)
This pattern creates a simple but powerful delivery mechanism:
Users open the extension UI (New Tab / popup / settings page). The extension fetches the JSON. If timestamp is newer, the HTML is injected and displayed. So when the server changes timestamp + HTML, the content is effectively “rolled out” to users opportunistically the next time they open the New Tab, without notice and without any extension update.

Observed evidence: server content changed over time
During analysis, the remote file content changed between two points in time. That operational behavior is the core risk: the endpoint is a live content channel.
/// message.json (Past JSON content)
{
"html":"<div><strong>You'll Love This: Lofi Girl Rumi Live Wallpaper</strong><br><a href='https://chromewebstore.google.com/detail/aeokfpjmojhklblbefpapaijonedodgg">Try It</a></div>",
"timestamp": 1773050000000
}
Most severe future case (how this could escalate)
Today, the impact may be confined to the extension’s own pages (New Tab / popup). The risk grows significantly if a future update expands where this logic can run.
Worst-case escalation scenario: a future extension update introduces content scripts that run broadly (e.g., "<all_urls>"). That could turn today’s “extension-page-only” remote HTML rendering into remote-controlled injection into arbitrary websites-raising the impact from “phishing inside an extension page” to “phishing overlays on real sites users visit.”
This matters because extension updates are common, and the existence of a remote messaging channel can later be combined with broader execution scope.
Indicators of Compromise(IOC's)
- Domains (
haberikra.com,gameograf.com) - URLs (
https://api.gameograf.com/popup/message.json) - Extension Identifiers
| Extension ID | Extension Name |
|---|---|
| mkggdfjjjljfnkcponiomlimekpeblgj | My Melody Kuromi Live Wallpaper |
| dbhpmaidefcfgjeohacicllkjhfclibe | Sukuna X Gojo Jujutsu Kaisen Gameograf |
| ocnpcjcfoipdokkiiohcamebepomkdng | Minecraft Live Wallpapers New Tab |
| jefmddbgpieeleledeklkchkhpjnmjnc | Blue Lock Wallpaper |
| bdlcjeifdnikloimicpijikkafmhdamf | Sakura and Smoke Live Wallpaper |
| adjmjhgedbgldhfldpdmeehifbbnlnkc | Brawl Stars Wallpaper |
| accpgkhiinomdhbbnadhcmbkdcbjoecp | Toyota Supra MK4 Live Wallpaper |
| achoehnlccncpkjkobddpfgbbdabjhcd | Wuling Blossoms Arknights Endfield Live Wallpaper |
| aeokfpjmojhklblbefpapaijonedodgg | Lofi Girl Rumi Live Wallpaper |
| adnclocfecihfailmdjllhdhflcomocd | Dark Bomber Fortnite Live Wallpaper |
| aaodljodpalikpjachaklikppjmbffef | Anime Girl Halloween Live Wallpaper New Tab |
| ackjocjeeoeighaijofijknnbopomfac | Hello Kitty Live Wallpaper |
| aeggcdnlgoodafmelonmibaaclbeejol | Chill Super Mario Pixel Live Wallpaper |
| aakikmpciidchmghpamchhhndmbobbeo | Dua Lipa Wallpaper Gameograf |
| aalpfbnlannkkdpaabpdegnmmmjpddke | Hello Kitty Live Wallpapers 4K |
| aanejgmmpenpmocplmghhfdillnhokhh | Hello Kitty Live Wallpaper |
| aaobffjniaghknbgjdkigmcnapghemfa | Momo Ayase Live Wallpaper |