Is Free Bulk Message Sender Global Gym Software safe?

High risk

Global Gym Software is high risk. The content script reads WhatsApp's stored account ID from WhatsApp Web and saves it as the login number. Testing captured a POST to wpsender.globalcrm.in/api/save_login_history.php with planted email_id/login_number; server returned OK.…

Global Gym Softwarev6.9.0Chrome Web Store
77Risk
Who publishes it

Global Gym Software - 1 other listing from the same operator, 1 of them carrying a finding

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

Publisher
Global Gym Software
Declared legal entity
Global Gym Software
Registered address
Anand, ANAND, ANAND, Gujarat 388001, IN
Registered contact
Pradeep Rajput

Same store account

1 other listing published from this account, 1k+ users between them. 1 of them carries a finding.

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

Publishers can request a review.

Findings

WhatsApp account identifiers sent to GlobalCRM

The content script reads WhatsApp's stored account ID from WhatsApp Web and saves it as the login number.

Testing captured a POST to wpsender.globalcrm.in/api/save_login_history.php with planted email_id/login_number; server returned OK.

Severity
High unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You open WhatsApp Web or start a WhatsApp sending flow while the extension is installed.

The extension's content script is configured to run on https://web.whatsapp.com/*.

The extension did this

The extension reads the WhatsApp account number from browser storage and saves it for its background service worker.

That saved number is later placed into a login-history POST to the GlobalCRM API.

Captured request
POSThttps://wpsender.globalcrm.in/api/save_login_history.php

Server returned {result:success} after receiving planted marker values in email_id and login_number.

Body
email_id=<redacted>&login_number=<redacted>&login_source=Email
Fields sent in the login-history request
  • Your WhatsApp login number
    +15551234567 (illustrative)

    This identifies the WhatsApp account active in your browser session.

  • Your extension account email
    user@example.com (illustrative)

    This can link the extension account or login context to the WhatsApp account number.

  • Login source label
    Email

    This describes how the extension categorizes the login context that is sent with the account number.

The code that does this

The source path from WhatsApp storage to the GlobalCRM POST

Readable version

Content script saves the WhatsApp login number

contentscript/content-v3-wa-send.js
checkWPLastLogin: async function() {  var e = await getSettings(),    e = (myContentObj.uiSettings = e.uiSettings, myContentObj.uiSettings.lastWPLoginNumber || myContentObj.uiSettings.currentWPLoginNumber),    t = myContentObj.uiSettings.loginProUser;  let n = getMyWPPhoneNumber(); - 1 != n.indexOf(":") && (n = n.split(":")[0]), 1 == t && "" != n && "" != e && n != e && (myContentObj.uiSettings.loginProUser = !1, myContentObj.uiSettings.userFreeTrialStarted = !1, n && (myContentObj.uiSettings.currentWPLoginNumber = n), await saveSettings(myContentObj.uiSettings), await setTimeIutInPromise(2e3), sendMessage({    command: "reloadPopupData"  }, function(e) {})), n && (myContentObj.uiSettings.currentWPLoginNumber = n, await saveSettings(myContentObj.uiSettings))}

Content script extracts the number from WhatsApp storage

contentscript/content-v3-wa-send.js
function getMyWPPhoneNumber() {  var e = "";  if ("" === gmpn()) try {    var t = window.localStorage.getItem("last-wid");    window.localStorage.getItem("last-wid-md") ? e = window.localStorage.getItem("last-wid-md").split("@")[0].substring(1).split(":")[0] : t && (e = window.localStorage.getItem("last-wid").split("@")[0].substring(1))  } catch (e) {    console.log(e)  } else e = gmpn();  return e}

Background service worker builds the POST body

js/background.js
saveUserLoginHistoryToServer: async function(e, t, s) {  var a = (await getSettings()).uiSettings,    n = a.loginProUser,    i = a.currentWPLoginNumber,    r = a.username,    o = new URLSearchParams;  1 == a.authUser && 0 == a.userFreeTrialStarted ? 1 == n ? (o.append("email_id", ""), o.append("login_number", i), o.append("login_source", "Number")) : (o.append("email_id", r), o.append("login_number", i), o.append("login_source", "Email")) : (o.append("email_id", ""), o.append("login_number", i), o.append("login_source", "Free")), fetch(consts.base_api_url + consts.save_login_history_api_url, {    method: "POST",    body: o  }).then(e => e.json()).then(e => s(e)).catch(e => s(e))}

Related auth-update path also includes the saved number

js/background.js
saveAuthSettingToDB: async function(c) {  return new Promise(async (t, e) => {    var s = (await getSettings()).uiSettings,      a = s.loginProUser,      n = s.currentWPLoginNumber,      i = s.total_scrapped_count,      r = s.username || "",      o = new URLSearchParams;    1 != s.authUser || 0 != s.userFreeTrialStarted || 1 == a ? (o.append("user_email", ""), n && "-" != n && o.append("user_mobile", n), o.append("user_login_type", "Mobile")) : (o.append("user_email", r), n && "-" != n && o.append("user_mobile", n), o.append("user_login_type", "Email")), "" != c && o.append("subscription_type", c), 0 != i && o.append("total_messages_count", i), fetch(consts.base_api_url + consts.auth_user_v2_api_url, {      method: "POST",      body: o    }).then(e => e.json()).then(e => t(e)).catch(e => t(e))  })}

API constants resolve the destination URL

js/consts.js
var consts = {	'base_api_url' : 'https://wpsender.globalcrm.in/api/',    'save_user_api_url' : 'save_user.php',    'save_login_history_api_url' : 'save_login_history.php',    'auth_user_v2_api_url' : 'auth_v2_users.php',    'auth_user_api_url' : 'auth_user.php',    'auth_mobile_user_api_url' : 'auth_mobile_user.php',    'banner_image_api_url' : 'banner_config.php',    'get_user_msg_config_api_url' : 'user_msg_config.php'};
External host that receives the login-history POST
    • wpsender.globalcrm.in

    Receives the extension's login-history request containing the WhatsApp login number, email context, and login source.

Email and license key are sent to developer server on activation

Activating this extension sends your email address and license key to the developer server.

Testing confirmed a POST to wpsender.globalcrm.in/api/save_user.php containing both activation fields.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-200
Source
Dynamic sandbox
What actually happens
You did this

The user submits the activation form.

The extension did this

The extension sends the user's email address and license key to the developer server.

Captured request
POSThttps://wpsender.globalcrm.in/api/save_user.php
Body
key=<redacted planted marker>&user_email=<redacted planted marker email>
Fields in the activation request
  • Your activation credentials
    BIRD-12345-KEY (illustrative)

    The request includes the license key used to activate the extension, which can identify an account or paid entitlement.

Observation

Observed during dynamic analysis: a planted marker email address and planted marker license key were transmitted in the activation POST request, and the server returned a success response.

WhatsApp phone number and email sent during authentication

Authenticating or starting a bulk-send flow sends account details to the developer server.

Evidence shows the request includes a WhatsApp phone number, email fields, subscription type, and message count, sent to wpsender.globalcrm.in.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

The user authenticates or starts a bulk-send operation.

The extension did this

The extension sends WhatsApp phone number and account data to the developer server.

Captured request
POSThttps://wpsender.globalcrm.in/api/auth_v2_users.php
Body
user_email=<redacted>&user_mobile=<planted marker value>&user_login_type=Mobile&subscription_type=premium&total_messages_count=99
Fields in the request
  • Your IP address
    203.0.113.24 (illustrative)

    Network address information can help associate account activity with a connection or location.

  • Extension storage data
    subscription_type=premium (observed during dynamic analysis)

    Stored login and subscription values can include account identifiers used during authentication.

Observation

Dynamic analysis confirmed that a planted marker value was transmitted in the WhatsApp phone number field and that the server returned profile data, showing the endpoint was active during testing.

What it can do

Permissions this extension asks for, as declared in version 6.9.0. 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 wpsender.globalcrm.in

    https://wpsender.globalcrm.in/api/*

  • See the address and title of every tab you have open

    tabs

  • Start, monitor and manage your downloads

    downloads

  • Show you desktop notifications

    notifications

  • Store data in your browser

    storage

  • Store an unlimited amount of data in your browser

    unlimitedStorage

Updated 30 September 2026kopehppnefjcdkpakdlchnnpcjghpeko