Is BeFrugal Tab safe?
BeFrugal is high risk. Every browser open, and hourly after, BeFrugal Tab reads your full installed-extension list, names, descriptions, IDs, versions, and sends it to a BeFrugal server, revealing which security tools, password managers, and VPNs you use.…
Who publishes itbefrugaldev - 2 other listings from the same operator, 2 of them carrying a finding
befrugaldev - 2 other listings from the same operator, 2 of them carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
2 other listings published from this account, 110k+ users between them. 2 of them carry a finding.
Shared hosts - 3 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
BeFrugal Tab transmits your full browser extension inventory every hour
Every browser open, and hourly after, BeFrugal Tab reads your full installed-extension list, names, descriptions, IDs, versions, and sends it to a BeFrugal server, revealing which security tools, password managers, and VPNs you use.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
The RegenDB alarm fires, or the daily digest hasn't run yet today.
This happens automatically on startup and once every 60 minutes, with no user interaction required.
Your complete browser extension list is read and sent to BeFrugal's servers.
Every extension you have installed, including its name, internal ID, description, and version, is collected and uploaded in a single POST request.
Server upserts the extension inventory against the UserToken; no body returned on success.
- Content-Type
- application/x-www-form-urlencoded
extensions=[{"id":"cjpalhdlnbpafiamejdnhcphjbkeiagm","name":"Adblock%20for%20Youtube%E2%84%A2","description":"Block%20ads%20on%20YouTube","version":"1.9.2"},{"id":"nkbihfbeogaeaoehlefnkodbefgpgknn","name":"MetaMask","description":"Ethereum%20browser%20extension","version":"11.13.1"},{"id":"cfhdojbkjhnklbpkdaibdccddilifddb","name":"Adblock%20Plus","description":"Block%20ads","version":"3.23"}]&UserToken=a8f3c1d7-4e2b-4a99-b891-2f3c4d5e6f7a&toolbarversion=ch-bfrwds2024.0.43- Extension IDnkbihfbeogaeaoehlefnkodbefgpgknn
The unique Chrome extension identifier, stable across versions and browsers. Reveals every security tool, password manager, and VPN you run.
- Extension nameMetaMask
The human-readable display name of each extension you have installed.
- Extension version11.13.1
The installed version of each extension, which can indicate whether you are running outdated software with known vulnerabilities.
- Extension descriptionEthereum browser extension
The full description text of each extension, as shown in the Chrome Web Store.
- User tokena8f3c1d7-4e2b-4a99-b891-2f3c4d5e6f7a
A persistent account token that ties each transmission to your BeFrugal identity.
Extension enumeration and upload, background.js:711-727
chrome.management.getAll(function(extensions) { var body = "extensions=" + JSON.stringify( extensions.map(function(ext) { return { id: ext.id, name: encodeURIComponent(ext.name), description: encodeURIComponent(ext.description), version: encodeURIComponent(ext.version) }; }) ) + "&UserToken=" + userToken + "&toolbarversion=" + toolbarVersion; fetch("https://tbwsjs.befrugal.com/wssimple.asmx/UserExtensionsUpsert", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: body });});Every 1 hour
The RegenDB alarm fires every 60 minutes. On each tick, digestRequest() checks whether the daily digest has already run; if not, it calls getDigestPartial(), which executes the chrome.management.getAll() upload.
- tbwsjs.befrugal.com
BeFrugal-owned backend that receives and stores the extension inventory alongside the user's account token (UserExtensionsUpsert endpoint).
BeFrugal Tab transmits UI interaction history to BeFrugal daily
Each day BeFrugal Tab records how you've used its interface: panels opened, search engine used, deal/reward clicks, and toolbar search/navigation counts.
This behavioral profile is sent to BeFrugal's servers in the daily digest request.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You click deals, use the rewards toolbar, or search through the extension.
Each interaction type is counted and timestamped in local storage as it occurs.
Your interaction history and current UI configuration are sent to BeFrugal once per day.
A parameter string encoding which panels are visible, which search engine you use, and how many times you clicked each feature is included in the daily digest POST.
Server returns JSON with retailer deals and user account data for new tab page population.
- Content-Type
- application/x-www-form-urlencoded
toolbarversion=ch-bfrwds2024.0.43&usertoken=a8f3c1d7-4e2b-4a99-b891-2f3c4d5e6f7a&toolbarmetrics=,KeepChangesDisplayed.1.1776506928,KeepChanges.1.1776506942,cleanup.1,isYahoo.1,RewardsBar.1,RewardsSplash.1- Search engine choiceisYahoo.1
Reveals whether you use Yahoo, Google, Bing, or DuckDuckGo as your default through the toolbar.
- Deal clicksDealClick.3.1776498000
Number of times you clicked on a cashback deal, counted since last digest.
- Rewards bar interactionsRewardsBar.1,RewardsActivity.1
Whether the rewards header bar and activity panels are visible, indicating how actively you use the rewards features.
- Omnibar search countRewardsToolbarSearch.7.1776501234
How many searches you have performed through the toolbar's search box.
- Shortcut clicksShortcutClicks.2.1776502100
Number of times you clicked the custom shortcuts on the new tab page.
- User tokena8f3c1d7-4e2b-4a99-b891-2f3c4d5e6f7a
The persistent account identifier that ties this interaction history to your BeFrugal account.
Metric collection and upload, background.js:659-734
setMetric — records each interaction
background.js:659setMetric: function(eventName, increment, value) { chrome.storage.local.get("analytics").then(function(stored) { var analytics = stored ? stored.analytics || stored : {}; if (increment) value = (analytics[eventName] || 0) + 1; analytics[eventName] = value; analytics.MetricTime = analytics.MetricTime || {}; analytics.MetricTime[eventName] = parseInt(new Date().getTime() / 1000); chrome.storage.local.set({ analytics: analytics }); });},getMetricParams — builds toolbarmetrics query string
background.js:671getMetricParams: function(analyticsData) { analyticsData = analyticsData || {}; var paramStr = "&toolbarmetrics="; var keys = Object.keys(analyticsData); for (var i = keys.length - 1; i >= 0; i--) { if (keys[i] !== "MetricTime") { var val = analyticsData[keys[i]]; if (val === true) val = "1"; else if (val === false) val = "0"; var timestamp = (analyticsData.MetricTime || {})[keys[i]]; paramStr += (i === keys.length - 1 ? "" : ",") + keys[i] + "." + val + (timestamp ? "." + timestamp : ""); } } return new Promise(function(resolve) { chrome.storage.local.get( ["searchEngine","extensionMode","ctl00_MainContent_dvClock","cleanUpNoClockImage", "dealsWrapper","favoriteRetailersContainer","bonusCashbackPanel","weatherPanel", "rewardsHeaderBar","rewardActivityContainer","topSites"], function(prefs) { if (prefs) { var engine = prefs.searchEngine || "Yahoo"; paramStr += ",cleanup." + (prefs.extensionMode === "cleanUp" ? 1 : 0); if (engine === "Yahoo") paramStr += ",isYahoo.1"; if (engine === "Google") paramStr += ",isGoogle.1"; if (engine === "Bing") paramStr += ",isBing.1"; if (engine === "DuckDuckGo") paramStr += ",isDuckDuckGo.1"; if (prefs.rewardsHeaderBar === "visible") paramStr += ",RewardsBar.1"; if (prefs.rewardActivityContainer === "visible") paramStr += ",RewardsActivity.1"; if (prefs.dealsWrapper === "visible") paramStr += ",RewardsDeals.1"; if (prefs.bonusCashbackPanel === "visible") paramStr += ",RewardsBonusCBRetailers.1"; if (prefs.favoriteRetailersContainer=== "visible") paramStr += ",RewardsFavorites.1"; if (prefs.weatherPanel === "visible") paramStr += ",RewardsWeather.1"; if (prefs.ctl00_MainContent_dvClock === "visible") paramStr += ",RewardsClock.1"; if (prefs.cleanUpNoClockImage === "visible") paramStr += ",RewardsSplash.1"; if (prefs.flashCashbackSection === "visible") paramStr += ",RewardsFlash.1"; resolve(paramStr); } } ); });},- partialjs.befrugal.com
BeFrugal-owned backend that receives the daily RetailerDigestPartial request carrying UI interaction metrics and panel state alongside the user's account token.
BeFrugal Tab leaks your most-visited site hostnames to Google on every new tab
Granting BeFrugal Tab access to top-visited sites, to populate new-tab shortcuts, makes each hostname transmit to Google's favicon service immediately, one GET per top site, disclosing that history whenever the new tab loads.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You grant the extension permission to see your most-visited sites, and the new tab page loads.
This happens once when you first click 'Add Shortcut' and approve the topSites prompt, and again each time the new tab renders the shortcuts.
The hostname of each of your most-visited sites is sent to Google in a separate HTTP request.
The extension sets an img.src to http://www.google.com/s2/favicons?sz=64&domain=<hostname> for each top site, which causes your browser to make a GET request that reveals each hostname to Google.
Google returns a favicon image (16x16 or 32x32 PNG). Seven such requests observed in DA: mail.google.com, youtube.com, yahoo.com, facebook.com, twitter.com, weather.com, wikipedia.org.
Favicon lookup that discloses top-site hostnames, PageScript.js:968-1014
var displayShortcut = function(name, url, callback) { var editAttr = document.getElementById("addShortcut").getAttribute("edit-shortcut"); var slot = document.querySelector( editAttr ? '[shortcut="' + editAttr + '"]' : ".shortcutGreyOuterContainer.inactive" ); if (slot) { slot.classList.remove("inactive"); slot.querySelector(".addShortcutText").innerText = name; slot.onclick = function() { digest.setMetric("ShortcutClicks", true); window.open(url, "_self"); }; // Sends the URL's domain to Google to fetch a favicon icon slot.querySelector("img").src = "http://www.google.com/s2/favicons?sz=64&domain=" + encodeURIComponent(url); if (callback) callback(); }};- Top-visited hostnameyoutube.com
The domain of each of your most-visited websites is sent to Google as the domain= query parameter.
- Full shortcut URLhttps://mail.google.com/mail/u/0/#inbox
The shortcut's full URL, including path, goes to encodeURIComponent before sending, so full URLs, not just domains, can be disclosed.
- www.google.com
Google favicon service, receives domain= parameter containing each of your top-visited hostnames via the /s2/favicons endpoint. Google is not affiliated with BeFrugal.
What it can do
Permissions this extension asks for, as declared in version 2024.0.43. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Read and change your data on befrugal.com
*://*.befrugal.com/*
Read and change your data on bfrl.us
*://*.bfrl.us/*
Add items to the right-click menu
contextMenus
Store data in your browser
storage
See, disable and uninstall your other extensions, including your security ones
management
Schedule its own background tasks
alarms
Run searches with your default search engine
search