Is Email GIFs by cloudHQ safe?

Medium risk

Email GIFs reads every signed-in Gmail address and sends the list to cloudHQ's servers.

On Gmail pages, the extension fetches each of up to 20 Gmail account slots to read the email address of every account signed in to the browser. It then posts that list, with the user's email, to cloudHQ roughly every two weeks without any user action. This includes accounts the user never uses with the extension.

cloudHQv1.0.0.3Chrome Web Store
49Risk
Who publishes it

cloudHQ - 10 other listings from the same operator, 7 of them carrying a finding

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

Publisher
cloudHQ
Declared legal entity
cloudHQ

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.

api.cloudhq.net
Also called by 1 other listing: GmailGPT
static.klipy.com
Also called by 2 other listings: Teams but (actually) good, giffpop-—-gif-keyboard-fo
klipy.com
Also called by 3 other listings, including Teams but (actually) good

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

Publishers can request a review.

Findings

Email GIFs reads all signed-in Gmail addresses and posts the list to cloudhq.net

Code analysis shows the extension requests /mail/u/N/ for up to 21 slots, reads each signed-in address, and posts the full list to cloudhq.net/main_pre_user/check on Gmail load, at most once per two weeks.

Severity
High unwanted
Type
Unexpected
CWE
CWE-359
Source
Static analysis
What actually happens
You did this

You open Gmail in a browser profile that is signed in to several Google accounts.

The extension did this

The extension fetches each account slot, collects the addresses, and posts the full list to cloudhq.net.

POST body sent to www.cloudhq.net/main_pre_user/check
  • email
    jane.doe@gmail.com (illustrative)

    The address of the account in the active tab.

  • email_switcher_list
    ["jane.doe@gmail.com","jane@examplecorp.com","j.doe.old@gmail.com"] (illustrative)

    Every Google address found in slots 0 to 20, including accounts never used with the extension.

  • email_or_login
    jane.doe@gmail.com (illustrative)

    Repeat of the active account address.

  • chrome_extension_name
    gmail_gifs

    Which cloudHQ product sent the request.

  • switch_login
    1

    Constant flag set to 1.

The code that does this

Enumeration, upload and relay code

Readable version

Loop bounds and URL pattern

// index runs 0..20 (g_switcher_account_emails_max_tries = 20)// each index N is fetched as:fetch('https://mail.google.com/mail/u/' + N + '/?sw=2', {method:'GET', mode:'cors'})  .then(r => r.text())  .then(html => { /* regex /var GLOBALS=([\s\S]*?)\;/ ; split on ','; first token passing fn_validate_email is taken as that slot's address */ });

Gate and send

// runs once per Gmail load unless a pre-check record newer than two weeks exists in chrome.storage.localif (!record || record.timestamp < twoWeeksAgo) {  collectSwitcherEmails(() => {    POST('https://www.cloudhq.net/main_pre_user/check', {      email, email_switcher_list, email_or_login, chrome_extension_name, switch_login: '1'    });  });}

Relay allow-list

// background: any request whose url starts with 'https://www.cloudhq.net/' is performed on the content script's behalf
Destination of the address list
    • www.cloudhq.net

    Receives the POST to /main_pre_user/check. The vendor domain is the only host the background relay accepts.

Reproduce it yourself

Console snippet that repeats the account-slot enumeration locally and prints the addresses found. It sends nothing.

Requires
  • Chrome with 2+ signed-in Google accounts
enumerate_gmail_accounts.js · js
// Run in the DevTools console on https://mail.google.com/mail/u/0/ with 2+ Google accounts signed in.// Reproduces the enumeration the content script performs (read-only, nothing is sent anywhere).(async () => {  const found = [];  for (let n = 0; n <= 20; n++) {    const html = await (await fetch(`https://mail.google.com/mail/u/${n}/?sw=2`)).text();    const m = /var GLOBALS=([\s\S]*?);/.exec(html);    if (!m) continue;    const hit = m[1].split(",").map(s => s.replaceAll('"', "").toLowerCase()).find(s => /^[\w.+-]+@[\w.-]+\.[a-z]{2,}$/.test(s));    if (hit && !found.includes(hit)) found.push(hit);  }  console.log("Addresses the page can enumerate:", found);})();
How to run it
  1. 1Sign in to two or more Google accounts.
  2. 2Open https://mail.google.com/mail/u/0/.
  3. 3Paste the script into the DevTools console.
  4. 4Compare the printed list with the email_switcher_list sent to cloudhq.net.
Observation

Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.

Where it sends data

Destinations our analysis observed Email GIFs by cloudHQ 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.cloudhq.netwidely used

    Email GIFs by cloudHQ sends data to www.cloudhq.net. A widely used service: 79 other extensions we have analysed send data here.

Updated 15 October 2026clndaiepoglbccffiodiickbmejhookm