Is WABiz Bulk Sender safe?

High risk

WABiz Bulk Sender transmits message content, recipient phone numbers, and Google account credentials to its vendor servers on every use.

Each time a message is sent, the extension POSTs the full message text and recipient phone numbers to wabiz.in. When the popup opens, it reads the signed-in Google account email, name, and a device ID and sends them to the same backend for license validation. The extension also writes the user's WhatsApp phone number and display name as cookies on wabiz.in, and logs contact list metadata to a Firebase Cloud Functions endpoint when contacts are exported.

WA Biz Senderv2.0.36Chrome Web Store
77Risk
Who publishes it

WA Biz Sender - no other listings under this identity, 2 shared hostnames

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

Publisher
WA Biz Sender

Shared hosts - 2 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.

webapp.joyz.ai
Also called by 2 other listings: WASender, So Lets Talk Digital - WA Sender
wabiz.in
Also called by 3 other listings: WABiz Free Bulk Sender (Lite), ASPIRA MENSAJES PLUS, WABulk Sender

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

Publishers can request a review.

Findings

WhatsApp message text and recipients sent to WABiz

HighunwantedCWE-359Dynamic sandbox

Sending WhatsApp messages through WABiz sends message text, recipient numbers, user ID, and version to wabiz.in stats endpoints.

What actually happens

You did this

You click send for a single WhatsApp message or start a bulk message run.

The send flow includes the message text you typed and the phone numbers selected for delivery.

The extension did this

The extension posts those send details to wabiz.in stats endpoints.

The source code passes single-message text and numbers directly, and bulk sends include taskData with numbers and messages arrays.

Fields sent by the message stats code

  • Message text
    Hi Jordan, your appointment is confirmed for 3 PM today.

    This is the WhatsApp message you typed or generated from a template.

  • Recipient phone number
    +15551234567

    This identifies who you are contacting through the extension.

  • Extension user ID
    9f4c1a22-73d6-4a3a-a1d7-0e4b52793c81

    This lets the backend connect the message activity to your extension account or license record.

  • Extension version
    2.0.32

    This adds context about the exact extension build used for the send.

  • Bulk send report
    Sent / Failed / Pending status for +15551234567

    This records which recipients were sent, skipped, failed, or still pending during a bulk run.

Captured request

POSThttps://wabiz.in/stats/singlemsg

Request body schema is defined in shipped source; traffic analysis did not capture a live single-message send body.

Headers
Content-Type
application/json

Captured request

POSThttps://wabiz.in/stats/bulkmsg

Request body schema is defined in shipped source; traffic analysis did not capture a live bulk-send body.

Headers
Content-Type
application/json

Captured request

POSThttps://wabiz.in/stats/reports-completion

Request body schema is defined in shipped source; traffic analysis did not capture a live completion-report body.

Headers
Content-Type
application/json

The code that does this

Shipped code paths that collect message data and post it to wabiz.in

Readable version

Bulk-send task assembly

deobfuscated/popup/send-message.js
async function n() {  let e = [],    n = [];  var t = {};  if (B())(e = M).forEach(() => {    n.push(getCustomizedMessage(0))  });  else {    e = D();    var o = await h.getExcelFileData();    if (o) {      var r = await h.getActiveSheet();      let a = await h.getStartIndex(),        s = await h.getFinalIndex();      t.usingExcel = !0, o.sheets[r].rows.forEach((e, t) => {        t >= a && t <= s && n.push(getCustomizedMessage(t))      })    } else await h.getCurrentMessageBulk(), e.forEach(() => {      n.push(getCustomizedMessage(0))    });    try {      var a = getVariablesInMessage().filter(e => e !== templatesControl.OPTOUT_VARIABLE_NAME);      t.msgPersonalization = !!a?.length    } catch (e) {      console.log("Error in setting personalization:", e)    }  }  m = !0, await U(), g = !1, S = OPERATION_SEND_MESSAGE, P = e.length, f = 0, _ = 0, s = oldAttchmentControl.getIsAttachmentSelected() ? oldAttchmentControl.getAttachment() : null, C = oldAttchmentControl.getAttachmentCount(), T = !1, await I(), i.updateView(), excelFileJSON && !B() && (t.fileName = fileName.split(".").slice(0, -1).join(".")), t.authid = authid, t.numbers = e, t.messages = n, t.contact = await void 0, l && isPro ? (t.messageGap = c, t.randomizeDelay = d) : (t.messageGap = 0, t.randomizeDelay = !1), b && isPro ? (t.batchGap = u, t.batchSize = p || e.length) : (t.batchGap = 0, t.batchSize = e.length), t.startTime = Date.now(), t.attachment = !!attachmentControl.getCount(), t.isCaption = !!attachmentControl.getIsCaption(), t.isPro = isGoldorSilver(), t.version = manifestData.version, analyticsInstance.logBulkMessageDetail(authid, t), await x(), t.tabid = await getActiveTab(), sendMsgToExtension({    from: POPUP_JS,    subject: MSG_SETUP_BATCH,    data: t  })}

Single-send click handler

deobfuscated/popup/send-message.js
$("#sendMessageBulk").click(async function() {  var e, t, a, s;  !isPro && isMsgTemplate() ? alertControl.showAlertProFeatureMsgCustomization() : B() ? ($("#sendMessageBulkWrapper").addClass("disabled is-loading"), await n()) : 1 === (e = D()).length ? (t = await void 0, a = getCustomizedMessage(0), s = e[0], analyticsInstance.logSingleMsgDetail(authid, a, s), sendMsgToActiveTab({    from: POPUP_JS,    subject: MSG_SEND_MESSAGE,    data: {      message: a,      number: s,      isAttachment: !!attachmentControl.getCount(),      isCaption: !!attachmentControl.getIsCaption(),      contact: t    }  })) : 0 < e.length && ($("#sendMessageBulkWrapper").addClass("disabled is-loading"), await n())})

Stats POST methods

deobfuscated/common/analytics.js
logSingleMsgDetail: async function(e, t, n) {  console.log("manifestData", s), await fetch("https://wabiz.in/stats/singlemsg", {    method: "POST",    mode: "cors",    cache: "no-cache",    credentials: "same-origin",    headers: {      "Content-Type": "application/json"    },    redirect: "follow",    referrer: "no-referrer",    body: JSON.stringify({      message: t,      phoneNumber: n,      userid: e,      version: s?.version    })  })},logBulkMessageDetail: async function(e, t) {  await fetch("https://wabiz.in/stats/bulkmsg", {    method: "POST",    mode: "cors",    cache: "no-cache",    credentials: "same-origin",    headers: {      "Content-Type": "application/json"    },    redirect: "follow",    referrer: "no-referrer",    body: JSON.stringify({      userid: e,      taskData: t    })  })}

Completion-report POST

deobfuscated/background/message-dispatcher.js
async function C(e) {  try {    await fetch(ROOT_URL + "/stats/reports-completion", {      method: "POST",      mode: "cors",      cache: "no-cache",      credentials: "same-origin",      headers: {        "Content-Type": "application/json"      },      redirect: "follow",      referrer: "no-referrer",      body: JSON.stringify({        data: {          ...e,          endTime: Date.now()        },        authid: i      })    })  } catch (e) {    console.error("Failed to send completion report:", e)  }}

External destination for the message stats requests

    • wabiz.in

    Receives single-message stats, bulk-message task details, and bulk completion reports from WABiz Bulk Sender.

WhatsApp Contact Export Metadata Sent to Firebase

MediumunwantedCWE-359Dynamic sandbox

Exporting WhatsApp contacts builds the spreadsheet locally, then posts export metadata to a Firebase Cloud Functions endpoint: account identifier and selected contact sources, including counts and the chosen group, label, or broadcast-list.

What actually happens

You did this

You export WhatsApp contacts through the extension.

The popup sends the selected contact sources to the active WhatsApp tab.

The extension did this

The extension sends export metadata to a Firebase Cloud Functions endpoint.

The metadata is posted after the spreadsheet is written.

Fields assembled for the contact-download metadata request

  • WhatsApp account identifier
    userid: +14155550132 (illustrative)

    Links the contact-export event to the WhatsApp account using the extension.

  • Contact count
    contactCount: 125 (illustrative)

    Shows how many contacts were included in the export action.

  • Selected contact sources
    allContacts: true, allChatContacts: false (illustrative)

    Shows which categories of WhatsApp contacts you selected for export.

  • Selected groups, labels, and broadcasts
    groupContacts: [{name: "Sales Leads", id: "120363025001234567@g.us"}] (illustrative)

    Can include the names and identifiers of WhatsApp groups, labels, or broadcast lists selected for export.

Captured request

POSThttps://us-central1-waplugin-34798.cloudfunctions.net/stats/contactdownload

The verification evidence records a POST to this endpoint containing userid and downloadData with contactCount.

Headers
Content-Type
application/json

The code that does this

The popup sends the contact-download selection to the WhatsApp tab

Readable version

Readable contact-download payload builder

popup/contact.js
function o() {    return {      authid: authid,      allContacts: s.allContactsEnabled,      allChatContacts: s.allChatContactsEnabled,      groupContacts: s.selectedGroups,      labels: s.selectedLabels,      broadcasts: s.selectedBroadcasts,      isPro: isGoldorSilver()    }  }

Readable contact-download click handler

popup/contact.js
$("#downloadAllContacts").click(() => {        s.showContactDownloadLimitLink = !isNinja(), t(), C(), sendMsgToActiveTab({          from: POPUP_JS,          subject: MSG_LIB_DOWNLOAD_CONTACTS,          data: o()        })

The code that does this

The content script posts contact-export metadata to Firebase

Readable version

Readable spreadsheet export and metadata call

content/content.js
async function downloadContactsFromLib(e) {  let t;  var n, o = {      ...e,      contactCount: 0    },    a = XLSX.utils.book_new(),    r = new Set;  if (e.allContacts && (n = await getSavedContactSheet(t = await contentLibhookInstance.getUserSavedContacts()), o.contactCount = t?.length, XLSX.utils.book_append_sheet(a, n, getValidSheetName(r, "Saved Contacts"))), e.allChatContacts && (n = await getWhatsAppContactSheet(t = await contentLibhookInstance.getUserWhatsAppContacts()), o.contactCount += t?.length, XLSX.utils.book_append_sheet(a, n, getValidSheetName(r, "Whatsapp Contacts"))), e.groupContacts)    for (var s of e.groupContacts) {      var c = await contentLibhookInstance.getUserGroupMemberContact(s.id),        c = (o.contactCount += c?.length, await getMemberContactSheet(c));      let e = s.name;      e = (e = e.replaceAll(/[\/\\\?\*\[\]]/gm, "-")).substring(0, 30), XLSX.utils.book_append_sheet(a, c, getValidSheetName(r, e))    }  if (e.labels)    for (var i of e.labels) {      var l = await contentLibhookInstance.getLabelMembersMessage(i.name),        E = await getMemberContactSheet(l);      o.contactCount += l?.length, XLSX.utils.book_append_sheet(a, E, getValidSheetName(r, i.name))    }  if (e.broadcasts)    for (var _ of e.broadcasts) {      var T = await contentLibhookInstance.getUserGroupMemberContact(_.id),        C = await getMemberContactSheet(T);      o.contactCount += T?.length, XLSX.utils.book_append_sheet(a, C, getValidSheetName(r, _.name))    }  XLSX.writeFile(a, "Contacts.xls"), logContactDownloadDetail(e.authid, o)}

Readable Firebase POST helper

content/content.js
let ROOT_URL = "https://us-central1-waplugin-34798.cloudfunctions.net",  CONTACT_DOWNLOAD_DETAIL_URL = ROOT_URL + "/stats/contactdownload";async function logContactDownloadDetail(e, t) {  try {    await fetch(CONTACT_DOWNLOAD_DETAIL_URL, {      method: "POST",      mode: "cors",      cache: "no-cache",      credentials: "same-origin",      headers: {        "Content-Type": "application/json"      },      redirect: "follow",      referrer: "no-referrer",      body: JSON.stringify({        userid: e,        downloadData: t      })    })  } catch (e) {}}

External host receiving the contact-export metadata

    • us-central1-waplugin-34798.cloudfunctions.net

    Firebase Cloud Functions endpoint that receives the contact-download metadata POST.

WhatsApp Phone Number Cookie on wabiz.in

MediumunwantedCWE-359Dynamic sandbox

When the popup has a logged-in WhatsApp profile, it writes the phone number and display name into cookies scoped to wabiz.in.

What actually happens

You did this

You open the extension popup while WhatsApp is logged in.

The popup asks the active WhatsApp tab for the current profile before updating its view.

The extension did this

The extension writes your WhatsApp phone number and name into wabiz.in cookies.

The cookies are named eu and un and are set for a seven-day lifetime.

Cookie values written for wabiz.in

  • WhatsApp phone cookie
    eu=+14155550132 (illustrative)

    Lets wabiz.in receive the WhatsApp phone number associated with the extension session.

  • WhatsApp display-name cookie
    un=Alex Chen (illustrative)

    Adds the WhatsApp display name next to the phone number.

  • Cookie lifetime
    604800 seconds (7 days)

    Keeps those values available to wabiz.in after the popup writes them.

The code that does this

The popup reads the WhatsApp profile and writes wabiz.in cookies

Readable version

Readable popup cookie writer

popup/popup.js
function updateView() {  function e(t, n, a) {    chrome.cookies.get({      url: a,      name: t    }, e => {      e || chrome.cookies.set({        url: a,        name: t,        value: n,        expirationDate: Date.now() / 1e3 + 604800      })    })  }  var t;  $("#wapluginVersion").html("WA Biz Sender - " + manifestData.version), loggedinUser && ($("#userDetails").html(`<span class="name">${loggedinUser.name}</span>` + '<span class="sep ml3 mr3">-</span>' + `<b>${loggedinUser.phoneNumber}</b>`), t = "https://wabiz.in/", e("eu", loggedinUser.phoneNumber, t), e("un", loggedinUser.name, t)), $("#mainMessageSendContainor").show(), isPageWebWhatsapp ? (activeTab === TAB_SHOWWHATSAPP_TAB && (activeTab = TAB_SEND_MSG), $("#" + TAB_SEND_MSG).show(), $("#" + TAB_PRO_ADD).show()) : (activeTab = TAB_SHOWWHATSAPP_TAB, $("#" + TAB_SEND_MSG).hide(), $("#" + TAB_PRO_ADD).hide()), $("#" + TAB_SHOWWHATSAPP_TAB).hide(), isPro && $("#" + TAB_PRO_ADD).hide(), (activeTab ? $("#" + activeTab) : $("#" + TAB_SEND_MSG)).tab("show"), isPro && alertControl.hideAllAlerts(), updateInfoBox(), updateSubscriptionFooter(), updateSendMessageView()}

Readable profile lookup

popup/popup.js
async function getUserInformation() {  var e = await sendMsgToActiveTab({      from: POPUP_JS,      subject: MSG_LIB_GET_LOGGEDIN_USER,      data: ""    }),    e = (e && (loggedinUser = e, sendMsgToExtension({      from: CONTENT_JS,      subject: MSG_SET_USER_PHONENUMBER,      data: loggedinUser    })), await sendMsgToActiveTab({      from: POPUP_JS,      subject: MSG_LIB_GET_LOGGEDIN_USER,      data: ""    }));  e?.phoneNumber && $("#whatsappDisconnectedWarning").addClass("d-none"), authPhoneNumber = e?.phoneNumber, authid = e?.phoneNumber, storageInstance.saveAuthId(e?.phoneNumber), updateView()}

The code that does this

Manifest permissions allow the cookie write

Readable version
    "permissions": [        "storage",        "cookies",        "https://wabiz.in/",        "alarms",        "identity",        "identity.email"    ],    "host_permissions": [        "https://wabiz.in/*"    ],

Cookie destination

    • wabiz.in

    Receives cookies scoped by the extension to https://wabiz.in/ when the browser later requests that site.

Where it sends data

Destinations our analysis observed WABiz Bulk Sender 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.

  • us-central1-waplugin-34798.cloudfunctions.net

    WABiz Bulk Sender sends data to us-central1-waplugin-34798.cloudfunctions.net. 8 other extensions we have analyzed send data here.

  • wabiz.in

    WABiz Bulk Sender sends data to wabiz.in. One other extension we have analyzed sends data here.

Updated 30 September 2026loooopmofpoapjmkhommonhhmhhbejao