Security Alert: Confirmed Malware
CryptoPriceSearch (BETA)
ID: hmdfjdmlicmgkkofgdjcndplcepgohgi
Supported Languages
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- http://cryptopricesearch.comView Profile
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
How do cryptocurrencies work? Learn about blockchain, bitcoin and gain more insight into mining cryptocurrency.
THIS EXTENSION IS FOR BETA TESTING. The production version can be found here - https://chrome.google.com/webstore/detail/cryptopricesearch/dgdbnbnhgiecnfdnkdlnadepkgekkooo Get CryptoPriceSearch, easily find pricing information, plus web search, free on your Chrome New Tab Extension. Comes with daily content to show you news, weather and more in a new Chrome window! By installing this extension, you agree to the End User License Agreement and Privacy Policy (eula.mindspark.com/eula/) This new tab extension is a product of Ask Applications, Inc. Permissions used & reasons: "Read and change your data on a number of websites" For our product to work, we require access to the websites we own and manage. "Replace the page you see when opening a new tab" This allows us to show you our product - new tab page with free web search. "Read your browsing history" This allows us to tailor product specific content or offers towards relevant information. "Display notifications" This allows us the option to send you updates or additional product offers once you’ve already enjoyed the free product. "Manage your apps, extensions, and themes" This allows us to help you disable or remove this product and also understand whether we are able to provide the best experience. Beta Release log: 13.953 : Non user facing attribution events 13.960 : Daily Content, Mac user consistency, optimized URL structure and bug fixes.
The extension overrides the browser's new-tab page (a known monetization-hijack pattern in the Mindspark/Ask toolbar family) and injects a content script into download.cryptopricesearch.com/blank.jhtml whose only job is to read window.localStorage values and ship them back to the background. This pairing of newtab takeover plus a hidden DLP (Download Landing Page) data-pickup script is the textbook 'partner/affiliate ID hand-off' mechanism used by adware toolbars.
"chrome_url_overrides": { "newtab": "ntp1.html" }, "permissions": [ "alarms", "cookies", "storage", "tabs", "webNavigation" ], "content_scripts": [ { "all_frames": true, "js": [ "/js/logger.js", "/js/util.js", "/js/localStorageContentScript.js" ], "matches": [ "https://download.cryptopricesearch.com/blank.jhtml" ], "run_at": "document_end" }Content script injected into the partner DLP page exposes an arbitrary getLocalStorage(key) RPC to the extension background, allowing it to siphon any localStorage value from the cryptopricesearch.com site. The key is dictated by the background (which requests 'toolbarData') so the page's localStorage can be exfiltrated to the extension and onward to logging endpoints. Generic 'read any key from localStorage' bridges are a classic data-exfiltration primitive.
var portNamePrefix = "localStorageContentScript";var channel;var commands = { getLocalStorage: function(data) { var storage = window.localStorage; var key = data && data.key; return Promise.resolve(storage.getItem(key)); }};function init() { var port = chrome.runtime.connect({ name: Util.generateGuid(portNamePrefix + "-" + chrome.runtime.id + "-") }); channel = { id: port.name, port: port, callbacks: new Map() }; port.onMessage.addListener(onConnectMessage);}The background script uses the privileged chrome.cookies API to enumerate ALL cookies on the cryptopricesearch.com domain and harvest them into a 'toolbarData' object that is later transmitted to logging endpoints. Bulk cookie enumeration on a third-party domain is a hallmark of credential/affiliate-tracker theft and is the reason the 'cookies' permission is granted.
ExtensionSetUpDLP.getDataFromCookies = function(domain) { var parseCookies = function(cookies) { var cookiesObj = cookies.reduce(function(obj, cookie) { obj[cookie.name] = cookie.value; return obj; }, {}); var toolbarData = ExtensionSetUpDLP.cleanToolbarData(cookiesObj); Logger.log("ExtensionSetUpDLP: The fetched DLP data looks like: " + JSON.stringify(toolbarData)); return toolbarData; }; return new Promise(function(resolve, reject) { chrome.cookies.getAll({ domain: domain }, function(cookies) { if (cookies.some(function(cookie) { return cookie.name === "toolbarId"; })) { resolve(parseCookies(cookies));On install, the extension silently opens an inactive tab to https://download.cryptopricesearch.com/blank.jhtml, asks the injected content script to dump a localStorage key, and then closes the tab. This 'open hidden tab → harvest data → close tab' pattern is unauthorized data collection performed without any user consent UI and is also used as a covert install-attribution channel.
ExtensionSetUpDLP.getDataFromLocalStorage = function(url, key, timeout) { return new Promise(function(resolve, reject) { chrome.tabs.create({ url: url, active: false }, function(tab) { ... var onLocalStorageContentScriptConnect = function(port) { ... if (port.sender.tab.windowId === tab.windowId && port.sender.tab.id === tab.id && port.name.indexOf(ExtensionSetUpDLP.localStorageContentScriptScopeName) === 0) { requestDataFromLocalStorageContentScript(port, key)Every event the extension fires (install, alarm, every 6h 'ToolbarActive' live-ping, error, info) builds a query string of identifying fields (toolbar GUID, partner ID, partner sub-ID, install date, country, user segment, etc.) and exfiltrates it to anx.cryptopricesearch.com. This is persistent telemetry that uniquely identifies the installation and tracks user activity over time.
UnifiedLogging.fireULOnBehalfOfDLP = function(url, data) { var searchParamsFromData = UnifiedLogging.getParamsFromData(data); url += ~url.indexOf("?") ? searchParamsFromData : searchParamsFromData.replace("&", "?"); fetch(url) .catch(Logger.warn);};...UnifiedLogging.createStandardData = function(eventName, state) { return { anxa: "CAPNative", anxv: state.replaceableParams.toolbarVersion, anxe: eventName, anxt: state.toolbarData.toolbarId, anxtv: state.replaceableParams.toolbarVersion, anxp: state.toolbarData.partnerId, anxsi: state.toolbarData.partnerSubId, anxd: state.replaceableParams.buildDate, f: "00400000", anxr: +new Date(), coid: state.toolbarData.coId, userSegment: state.toolbarData.userSegment };};On the very first new-tab open, the extension injects a hidden iframe pointing at a templated pixel URL (e.g. install_pixels.jhtml or conversion.html) carrying partnerId, sub_id, coId, toolbarId and additional s2-s5 sub-affiliate slots, then removes the iframe. This is a covert install-attribution / conversion-tracking exfiltration channel disguised as a 1x1 pixel.
FirstOpenNT.firePixel = function(state) { return new Promise(function(resolve) { if (!state.toolbarData.pixelUrl || !state.configVars) return resolve(); var pixelURL = FirstOpenNT.replaceChildDomainToParent(state.toolbarData.pixelUrl, state.configVars .downloadDomain); var iframe = document.createElement("iframe"); iframe.addEventListener("load", function(e) { iframe.parentNode.removeChild(iframe); Logger.log("UnifiedLogging: pixel fired " + pixelURL); }, true); iframe.setAttribute("src", pixelURL); document.body.appendChild(iframe); state.toolbarData.pixelUrl = null; resolve(); });};On every cryptopricesearch.com page (document_start), the extension publishes the user's toolbar GUID, partner IDs, install date and version into the page via postMessage and writes 'mindsparktb_*' identifying cookies. This silently tags the host page with a persistent fingerprint that any page-level script can read and forward off-domain — direct unauthorized data leakage from the extension to web pages.
ExtensionDetectForPPContentScript.getMessageListener = function(state) { return function(message) { if (message.origin !== document.location.origin) return; var data = typeof message.data === "string" ? JSON.parse(message.data) : message.data; if (data.from !== ExtensionDetectForPPContentScript.fromExtension && data.status === ExtensionDetectForPPContentScript.requestStatus) { var data_1 = { toolbarId: state.toolbarData.toolbarId, partnerId: state.toolbarData.partnerId, partnerSubId: state.toolbarData.partnerSubId, installDate: state.toolbarData.installDate, toolbarVersion: state.replaceableParams.version, toolbarBuildDate: state.replaceableParams.buildDate, }; window.postMessage(JSON.stringify(ExtensionDetectForPPContentScript.getMessage(state, ExtensionDetectForPPContentScript.requestStatus, data_1)), document.location.origin); } };};ExtensionDetectForPPContentScript.setInstalledCookies = function(toolbarId) { var hourFromNow = new Date(Date.now() + (1 * 60 * 60 * 1000)) .toUTCString(); document.cookie = "mindsparktb_" + toolbarId + "=true; expires=" + hourFromNow + "; path=/"; document.cookie = "mindsparktbsupport_" + toolbarId + "=true; expires=" + hourFromNow + "; path=/";};The extension fetches a remote JSON ('notifications-config.json') from download.cryptopricesearch.com and uses its contents (title, image, linkUrl) to push OS-level notifications via self.registration.showNotification, then on click opens the operator-supplied URL in a new tab. This gives the remote operator a server-controlled channel to push arbitrary advertising / phishing prompts into Chrome and steer users to attacker-chosen URLs.
var trackLevelConfigUrl = state.configVars.notificationConfigBaseUrl + "/" + state.configVars .parentCobrandID + "/" + state.configVars.parentTrackID + "/notifications-config.json";var cobrandLevelConfigUrl = state.configVars.notificationConfigBaseUrl + "/" + state.configVars .parentCobrandID + "/notifications-config.json";...Promise.all([fetch(trackLevelConfigUrl, requestInit), fetch(cobrandLevelConfigUrl, requestInit)]) ... NotificationService.handleNotificationClick = function(notificationBaseDetails) { chrome.tabs.create({ url: notificationBaseDetails.linkUrl }, function(tab) {Periodically calls params.cryptopricesearch.com/ptag with cobrand/vendor/installDate/source/track and accepts a server-provided 'searchParams' blob (PC, FROM, PTAG codes) that the extension stores and pushes into open new-tab pages. The remote server can therefore silently change which monetization/affiliate parameters are appended to user searches at runtime — a remote behavioral/redirection control channel.
PTagService.getPTagServiceUrl = function(state) { var url = state.configVars.pTagServiceUrl; var cobrand = Util.getCobrandFromPartnerId(state.toolbarData.partnerId, state.toolbarData.coId); var vendorId = state.toolbarData.vendorId || PTagService.getDefaultVendorId(); var installDateForPTagService = PTagService.getFormattedInstallDate(state.toolbarData.installDate); var source = PTagService.getSourceValue(); var track = state.replaceableParams && state.toolbarData.dataSource === "extension" ? "VRLTRK" : state.replaceableParams.trackID; return url + "?cobrand=" + cobrand + "&vendor=" + vendorId + "&installDate=" + installDateForPTagService + "&source=" + source + "&track=" + track;};...PTagService.handlePTagServiceResponse = function(pTagServiceResponse) { ... var newSearchParams = JSON.stringify(pTagServiceResponse.searchParams); ... extensionState.toolbarData.searchParams = newSearchParams; ... if (searchParamsChanged) { var data = { data: pTagServiceResponse.searchParams, destination: "searchParams", }; ConnectionManager.sendMessageToOpenWTT(data); }Hooks chrome.tabs.onUpdated and force-navigates any tab whose URL matches the configured new-tab patterns (or one of nine hp.* domains in domainsToRedirectToNewTab — hp.myway.com, hp.ask.com, hp.mysearch.com, hp.mywebsearch.com, hp.tb.ask.com, hsts.myway.com, hp.norton.myway.com, hp.forgebrowser.com) to the extension's own ntp1.html. This is search/homepage hijacking that overrides legitimate user navigation.
NewTabToExtensionPageRedirect.newTabRedirectHandler = function(state, tabId, changeInfo, tab) { var capturedTabURLStr = changeInfo.url; if (!capturedTabURLStr) return; Logger.log("NewTabToExtensionPageRedirect: newTabRedirectHandler from " + capturedTabURLStr); var capturedURL = new URL(capturedTabURLStr); var embeddedNewTabURL = PageUtils.getNewTabResourceUrl() + capturedURL.search; var missingNTParamsInCapturedURL = UrlUtils.getMissingNTParamsInCapturedURL(state, capturedURL); var finalUrl = PageUtils.appendParams(embeddedNewTabURL, missingNTParamsInCapturedURL); chrome.tabs.update(tabId, { url: finalUrl });};Catches navigations to other 'home page' domains (hp.myway.com, hp.ask.com, hsts.myway.com, hp.norton.myway.com, etc.) and silently rewrites them to the extension's own newtab page, preserving tracking parameters. This is unauthorized cross-site redirection that hijacks legitimate home-page/search traffic the user (or another extension) intended to load.
OtherDomainToExtensionPageRedirect.newTabRedirectHandler = function(tabId, changeInfo) { var tabURLString = decodeURI(changeInfo.url); var tabUrlParams = UrlUtils.parseQueryString(UrlUtils.parseUrl(tabURLString) .getQueryString()) .nameValues .filter(function(param) { return "ruid" === param.name || "rd" === param.name; }); var url = PageUtils.appendParams(PageUtils.getNewTabResourceUrl(), tabUrlParams.map(function(param) { return param.name + "=" + param.value; })); chrome.tabs.update(tabId, { url: url });};On every webNavigation.onCompleted event, the extension enumerates ALL iframes in the tab (chrome.webNavigation.getAllFrames), inspects their URL hashes for a partner-product signature, and on a match fires a 'ToolbarDetect' tracking call AND force-redirects the tab. Reading the URL of every sub-frame on every navigation is broad surveillance and the auto-redirect amounts to active hijacking on partner page visits.
ExtensionDetectForFP.alreadyInstalledRedirectHandlerForChildProduct = function(state, details) { if (details.frameId !== 0) return; chrome.webNavigation.getAllFrames({ tabId: details.tabId }, function(frameDetails) { frameDetails.some(function(frame) { var url = new URL(frame.url); if (url.hash) { var hashParams_1 = ExtensionDetectForFP.extractHashParams(url.hash); ... ExtensionDetectForFP.fireToolbarDetect(hashParams_1, state, dlpEndpoint_1); ... PageUtils.redirectToUrl(details.tabId, redirectUrl, true)Exposes a 'webtooltab' RPC reachable from any cryptopricesearch.com page (via the WebTooltabAPIProxy content script and chrome.runtime.sendMessage bridge) that can call chrome.management.uninstallSelf with showConfirmDialog explicitly set to false, AND can rewrite the post-uninstall survey URL on the fly. A web page can therefore silently uninstall the extension and redirect the user to an attacker-chosen 'survey' URL — an inappropriate cross-origin privilege exposure.
features = { management: { uninstall: function(customUninstallOptions) { var uninstall = function() { return new Promise(function(resolve, reject) { var doUninstall = function() { try { var uninstallOptions = { showConfirmDialog: !!customUninstallOptions && customUninstallOptions .showConfirmDialog || false }; ... var result = chrome.management.uninstallSelf(uninstallOptions); ... }); }; if (customUninstallOptions.suppressSurvey) { ... chrome.runtime.setUninstallURL(customUninstallOptions.uninstallSurveyUrl || "", function() {Schedules a recurring chrome.alarms ping (every 21,600,000 ms / 6 hours per config) that beacons the user's unique toolbar/partner/cwsid to anx.cryptopricesearch.com/tr.gif. This is a persistent 'are-you-alive' telemetry pixel that lets the operator monitor active install counts and user uniqueness with no opt-out.
UlLivePingExecutor.startULPing = function(state) { Logger.log("UlLivePingExecutor: startULPing function has been called"); var interval = state.configVars.livePing.interval; var lastPing = state.lastLivePing; var delta = Math.max(0, interval - (Date.now() - (lastPing || 0))); if (delta === 0) { UnifiedLogging.fireToolbarActiveEvent() .then(function() { state.lastLivePing = Date.now(); ... }); delta += interval; } chrome.alarms.create(UlLivePingExecutor.alarmName, { when: Date.now() + delta, periodInMinutes: interval / 1000 / 60 });};Calls a remote 'dormant-service' URL (templated with toolbar/partner identifiers) to ask the server whether the current user is 'dormant', then suppresses or shows ad notifications accordingly. The extension is reporting per-user activity status to a remote server purely for ad-targeting decisions — silent behavioral profiling without disclosure.
NotificationService.updateDormantStatus = function(dormantServiceURL, notificationServiceState) { if (!dormantServiceURL) { return Promise.reject(NotificationService.createWarning("dormant-service", "DormantAPIURL is empty.")); } StateStorage.get(ExtensionSetUp.extensionStateKey) .then(function(extensionState) { var finalDormantServiceURL = TextTemplate.parse(dormantServiceURL, extensionState.replaceableParams); ... }) .then(fetch) .then(function(response) { ... notificationServiceState.isDormantUser = response.isDormant;Generic remote-config fetcher used by NotificationService, DailyContentService and PTagService to pull JSON from operator-controlled URLs (download.cryptopricesearch.com, params.cryptopricesearch.com) without integrity checks or signing. The fetched JSON drives notification content/links, daily-content scheduling and search parameters, giving the operator persistent server-side control over extension behavior post-install.
RemoteConfigLoader.fetchRemoteConfig = function(remoteConfigUrl) { return new Promise(function(resolve, reject) { Logger.log("RemoteConfigLoader: fetchConfig " + remoteConfigUrl); fetch(remoteConfigUrl) .then(function(response) { if (!response.ok) return reject(new Error("error fetching " + remoteConfigUrl + " status: " + response.status)); ... return resolve(response.json()); })Schedules a chrome.alarms job that fires daily at 02:00 local time to forcibly open a new browser window pointing at the extension's monetized newtab (ntp?daily=1). This auto-opens promotional content while the user is away — unsolicited tab/window injection driven by a recurring alarm and a remote enable/disable flag.
DailyContentService.scheduleDailyContent = function() { var whenToShowDailyContent = DailyContentService.getNextTimeToSchedule(); chrome.alarms.get(DailyContentService.dailyContentAlarmName, function(alarm) { if (alarm) return; chrome.alarms.create(DailyContentService.dailyContentAlarmName, { when: whenToShowDailyContent }); });};DailyContentService.getNextTimeToSchedule = function() { var currentDate = new Date(); var todayTimeToShowTheDailyContent = new Date() .setHours(DailyContentService.hourToDisplayDailyContent, 0, 0, 0); return currentDate.getTime() < todayTimeToShowTheDailyContent ? todayTimeToShowTheDailyContent : currentDate.setHours(24 + DailyContentService.hourToDisplayDailyContent, 0, 0, 0);};DailyContentService.openDailyContentWindow = function() { return DailyContentService.queryingForDailyContentOpenTabs() .then(function(tabs) {Bridges window.postMessage from cryptopricesearch.com / the embedded newtab into chrome.runtime.sendMessage so web pages can invoke the privileged 'webtooltab' API surface (uninstall, disableDaily, getDailyStatus). The 'isValidSource' check only verifies the current document URL is internal, not the message author, weakening the trust boundary between web content and extension privileges.
function onWTTMessage(e) { if (isWebTooltabMessage(e)) { isValidSource() .then(function() { Logger.log("WebToolTabAPIProxy: onWTTMessage: received message " + JSON.stringify(e.data)); var msgToExtensionWTTAPI = { name: "webtooltab", data: JSON.parse(e.data) }; chrome.runtime.sendMessage(msgToExtensionWTTAPI, onWTTMessageResponse); })By severity
Versions scanned
Showing 1 of 2 scanned versions with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 13.986.19.63396 | 18 |
Files with findings
16 distinct paths — top paths by unique finding count:
- js/extensionSetUpDLP.js2
- js/notificationService.js2
- js/dailyContentService.js1
- js/extensionDetectForFP.js1
- js/extensionDetectForPPContentScript.js1
- js/firstOpenNT.js1
- js/localStorageContentScript.js1
- js/newTabToExtensionPageRedirect.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.