Is Bardeen: Automate Browser Apps with AI safe?
Bardeen is medium risk. Bardeen requests <all_urls> and tracks tab creation, switch, close, navigation, focus change across your whole session, not just automated pages. DA confirmed this live. Full tab history is held in memory for automation; no exfil seen.
Who publishes itBardeen Inc - no other listings under this identity, 1 shared hostname
Bardeen Inc - no other listings under this identity, 1 shared hostname
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 1 hostname
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
Background Worker Tracks Every Tab's URL and Address-Bar Navigation
Bardeen requests <all_urls> and tracks tab creation, switch, close, navigation, focus change across your whole session, not just automated pages.
DA confirmed this live.
Full tab history is held in memory for automation; no exfil seen.
You navigate between pages, switch tabs, or type a URL into the address bar, anywhere on any website.
This includes ordinary browsing that has nothing to do with running an automation.
The background service worker records the full URL, transition type, and tab/window state for every tab in an in-memory session map.
Navigations typed directly into the address bar are explicitly flagged and distinguished from other transition types.
Tab, window, and navigation listeners are attached once when the background service worker starts and remain active for the whole browsing session -- tracking continues on every site regardless of whether an automation is currently running.
| Field | Value | Why it matters | |
|---|---|---|---|
Full page URL | https://accounts.google.com/signin/v2/identifier | Every page you navigate to, including the exact URL, is captured for every open tab, not just the active one. | |
Address-bar transition type | typed (from_address_bar) | The extension records whether a URL was typed directly into the address bar, reached by a reload, or reached another way. | |
Tab and window state | active: true, pinned: false, windowId: 912 | Whether the tab is active, pinned, highlighted, or incognito is tracked alongside its URL. | |
Tab identifier | 1585209824 | A numeric ID ties every tracked event back to the same browser tab across its lifetime. |
Tab/navigation listeners and per-tab session handler, shipped vs. deobfuscated
chrome.tabs.onActivated.addListener((...args) => {
return eventQueue.push({ type: "tabs.onActivated", args });
});
chrome.tabs.onUpdated.addListener((...args) => {
return eventQueue.push({ type: "tabs.onUpdated", args });
});
chrome.tabs.onRemoved.addListener((...args) => {
return eventQueue.push({ type: "tabs.onRemoved", args });
});
chrome.tabs.onCreated.addListener((...args) => {
return eventQueue.push({ type: "tabs.onCreated", args });
});
chrome.windows.onRemoved.addListener((...args) => {
return eventQueue.push({ type: "windows.onRemoved", args });
});
chrome.windows.onFocusChanged.addListener((...args) => {
return eventQueue.push({ type: "windows.onFocusChanged", args });
});this.handleBrowserEvent = (event) => {
switch (event.type) {
case "tabs.onRemoved": {
let [tabId] = event.args;
this.untrackTab(tabId);
this.uimodules.handleTabRemoved(tabId);
this.emit("tab_closed", tabId);
break;
}
case "tabs.onCreated": {
let [tab] = event.args;
let session = this.trackTab(tab);
session && this.emit("tab_created", session.getTabItem());
break;
}
case "tabs.onUpdated": {
let [tabId, , tab] = event.args;
let session = this.tabSessions.get(tabId);
if (session) {
let newState = session.handleStateChange(tab);
newState.active && this.emit("active_tab_change", toTabItem(newState, newState.windowId));
} else {
this.trackTab(tab);
tab.active && this.emit("active_tab_change", toTabItem(tab, tab.windowId));
}
break;
}
case "tabs.onActivated": {
let [{ tabId }] = event.args;
let session = this.tabSessions.get(tabId);
this.activeTab && this.activeTab.handleStateChange({ active: false });
if (session) {
this.activeTab = session;
session.handleStateChange({ active: true });
this.emit("active_tab_change", session.getTabItem());
} else {
this.activeTab = null;
getTab(tabId).then((tab) => {
this.activeTab = this.trackTab(tab);
this.emit("active_tab_change", toTabItem(tab, tab.windowId));
}, () => {});
}
break;
}
case "webNavigation.onCommitted": {
let [details] = event.args;
this.handleWebNavigationCommitted(details);
}
}
};
this.handleWebNavigationCommitted = async (details) => {
let { tabId, transitionType, transitionQualifiers, url } = details;
if (details.frameId !== 0) return;
let session = this.tabSessions.get(tabId);
if (session && ((await session.getURL() === url && transitionType === "typed" && transitionQualifiers.includes("from_address_bar")) || transitionType === "reload")) {
this.log.silly("Redirect detected", { tabId, url, transitionType, transitionQualifiers });
session.emit("navigate", url, url);
}
};Dynamic analysis confirmed the tracking machinery is live during real browsing: the background service worker issued repeated chrome.tabs.get calls immediately after each navigation, and its own "BrowserTabSession" log entries fired throughout a multi-site browsing session. We did not capture this URL/tab data being transmitted off the device in the same test session -- the confirmed behavior is that the extension holds a live, full-navigation session map in the background service worker's memory, available to its automation engine, for every open tab.