Security Alert: Confirmed Malware
Плагин ГИС НР
ID: cdjkkeofanojcdolaakkckkmfcjejlij
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- esepextView Profile
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
Расширение предназначено для видеофиксации действий, осуществляемых на электронных площадках и на сайте ЕИС.
Расширение является встраиваемым в браузер модулем (плагином) и предназначено для выполнения функций по сбору, протоколированию, обработке и хранению данных из информационных систем, используемых в процессе проведения электронных процедур и заключения контрактов на электронных площадках и ЕИС. Плагин ГИС НР позволяет защитить права участников контрактной системы в ходе проведения электронных процедур с помощью встроенного видеоплеера. Пользователь имеет возможность зафиксировать нарушение и/или ошибку, произошедшую на электронной площадке и/или официальном сайте ЕИС, включив запись своей работы на площадке. Записанное видео может быть направлено в ФАС или иной орган в качестве подтверждающих материалов. Важно: фиксации подлежит полный экран компьютера пользователя, включая панель задач и системное время. Во избежание недоразумений во время работы модуля не следует демонстрировать на экране вашего компьютера информацию личного характера, не имеющую отношения к работе на электронной площадке, ЕИС и Официальном сайте торгов.
The extension registers a blocking `webRequest` listener against ALL http and https URLs (`http://*/*` and `https://*/*`), intercepts every main-frame navigation, and exfiltrates the full URL, precise load timing, and HTTP status code to the local server via `SetMarketplaceState`. This constitutes covert surveillance of the user's complete browsing history across every website they visit, not just the stated government procurement portals.
var urlFilter = { urls: ["http://*/*", "https://*/*"]};var requestMap = {};var requestStatusMap = {};function sendSetMarketplaceState(url, time, error, statusCode) { if (url.indexOf('127.0.0.') >= 0) return; if (url.indexOf('localhost') >= 0) return; if (!time) return; if (error && !statusCode) return; var data = { 'cmd': 'SetMarketplaceState', 'params': { 'url': url, 'time': time, 'error': error, 'errorCode': statusCode } }; CommandService.sendRequestToServer(data).then(function() {});}The `onBeforeRequest` listener is registered with the `blocking` extra-info spec, meaning the extension can delay or modify every outgoing HTTP/HTTPS request across all websites. Combined with the universal URL filter, this gives the extension a man-in-the-browser position on all traffic. Even though no modification is performed in the current code, the `blocking` capability creates a structural capability for request tampering.
webRequest().onBeforeRequest.addListener(function(details) { if (details.type != 'main_frame' || details.url.indexOf(CommandService.SERVICE_HOST) == 0) return; requestMap['' + details.requestId] = new Date().getTime();}, urlFilter, ["blocking"])webRequest().onCompleted.addListener(function(details) { if (details.type != 'main_frame' || details.url.indexOf(CommandService.SERVICE_HOST) == 0) return; var time = getTime(details.requestId); sendSetMarketplaceState(details.url, time, false, getRequestStatus(details.requestId));}, urlFilter);Every tab activation, tab update, and browser window focus change triggers extraction of the active tab's full URL and page title, which are then transmitted to the local server. This creates a continuous real-time log of every page the user visits (URL + human-readable page title), sent outside the browser on each navigation event, far beyond any stated functionality of recording government procurement sessions.
function sendActivPageUrl(url, title) { if ($rootScope.settings && ($rootScope.app.storage.activUrl != url || $rootScope.app.storage.activPageTitle != title)) { $rootScope.app.storage.activUrl = url; $rootScope.app.storage.activPageTitle = title; var data = { 'cmd': 'SetActivePage', 'params': { 'url': url, 'title': title } }; CommandService.sendRequestToServer(data).then(function() { $rootScope.app.workflow.getStatus(); }); }}// Изменена активная вкладкаtabs().onActivated.addListener(function(info) { $scope.sendActivTab(info.tabId);});// Обновлена страницаtabs().onUpdated.addListener(function(id, info, tab) { $scope.sendActivTab(tab.id);});bwindows().onFocusChanged.addListener(function(windowId) { // ... $scope.sendActivTab(tabs[0].id);});A `PostTelemetry` command that includes the user's current active URL is sent to the local server whenever internet connectivity state, time synchronization state, or marketplace availability changes. This constitutes an additional exfiltration channel that correlates the user's current browsing URL with internal system state changes, building a richer behavioral profile.
$rootScope.app.workflow.sendTelemetry = function(oldStatus, newStatus) { var f = false; if (oldStatus.internetState != newStatus.internetState) f = true; if (oldStatus.timeState != newStatus.timeState) f = true; if (oldStatus.marketplace && newStatus.marketplace && oldStatus.marketplace.available != newStatus.marketplace.available) f = true; if (f) { var data = { 'cmd': 'PostTelemetry', 'params': { 'url': $rootScope.app.storage.activUrl } }; CommandService.sendRequestToServer(data).then( function(info) {}); }}The extension exposes its runtime status and version to any external page matching `*://localhost/*` via `chrome.runtime.onMessageExternal`. Any locally-served web application can query the extension's running state and version number without user consent, enabling the local server software (or any attacker who can serve content on localhost) to probe extension state and coordinate behavior.
chrome.runtime.onMessageExternal.addListener( function(request, sender, sendResponse) { if (request) { if (request.message) { if (request.message == "plugin_status_request") { sendResponse({ "is_running": $rootScope.app.storage.serverAvailable, "version": $rootScope.app.storage.status.version }); } } } return true; });The content script, injected into ALL frames of ALL URLs, listens for `window.postMessage` from any origin and responds using the hardcoded plaintext secret `"gisnr_secret_key"`. Because the secret is embedded in the extension's source code (visible via chrome://extensions or the CRX), any webpage that knows this string can detect the extension's presence and version across every site the user visits, enabling cross-site extension fingerprinting. Responses are broadcast with `"*"` target origin, leaking the secret key back to any origin.
window.addEventListener("message", function(event) { if (event.data.secret_key && (event.data.secret_key === "gisnr_secret_key") && event.data.source === "page") { if (event.data.type) { switch (event.data.type) { case 'is_extension_installed': window.postMessage({ source: "content_script", type: 'extension_installed', secret_key: "gisnr_secret_key", version: "2.4" }, "*"); break; } } }}, false);A unique GUID is generated at service initialization time and appended as `id` to every command sent to the local server. This GUID persists for the lifetime of the background page and acts as a stable per-session identifier, allowing the local server to correlate all browsing data (URLs, timings, telemetry) to a single installation. Combined with the URL tracking, this creates a deanonymizing user fingerprint sent with every data submission.
this.guid = createGuid();this.sendRequestToServer = function(data) { data.id = this.guid; var deferred = $q.defer(); $http .post(this.HOST + $rootScope.settings.pluginCommandPort + this.SERVICE_COMMAND_SUFFIX, data) .success( function(response) { $rootScope.app.workflow.serverChangeActive(true, false); ... }).error(function(error) { $rootScope.app.workflow.serverChangeActive(false, false); deferred.reject(error); }); return deferred.promise;};By severity
Versions scanned
Showing 2 of 9 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 2.10 | 4 |
| 2.4 | 7 |
Files with findings
6 distinct paths — top paths by unique finding count:
- js/background/monitors/request-monitor.js3
- js/background/controllers/background-controller.js2
- js/background/monitors/activ-page-monitor.js2
- js/contentScripts/content-script.js2
- js/background/keepalive.js1
- js/background/services/command-service.js1
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.