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.32Chrome Web Store
75Risk

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

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

WhatsApp message text and recipients sent to WABiz

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

Single sends post to /stats/singlemsg; bulk sends also post recipients, messages, and completion report.

01EvidenceCAUSE EFFECT
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.

02EvidenceFIELD TABLE
Fields sent by the message stats code
FieldValueWhy it matters
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
+15551234567This identifies who you are contacting through the extension.
Extension user ID
9f4c1a22-73d6-4a3a-a1d7-0e4b52793c81This lets the backend connect the message activity to your extension account or license record.
Extension version
2.0.32This adds context about the exact extension build used for the send.
Bulk send report
Sent / Failed / Pending status for +15551234567This records which recipients were sent, skipped, failed, or still pending during a bulk run.
03EvidenceNETWORK CAPTURE
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-Typeapplication/json
04EvidenceNETWORK CAPTURE
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-Typeapplication/json
05EvidenceNETWORK CAPTURE
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-Typeapplication/json
06EvidenceCODE COMPARE
The code that does this

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

What it actually does
Bulk-send task assemblydeobfuscated/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 handlerdeobfuscated/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 methodsdeobfuscated/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 POSTdeobfuscated/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)
  }
}
07EvidenceTHIRD PARTY LIST
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.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

WhatsApp Contact Export Metadata Sent to Firebase

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.

01EvidenceCAUSE EFFECT
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.

02EvidenceFIELD TABLE
Fields assembled for the contact-download metadata request
FieldValueWhy it matters
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.
03EvidenceNETWORK CAPTURE
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-Typeapplication/json
04EvidenceCODE COMPARE
The code that does this

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

What it actually does
Readable contact-download payload builderpopup/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 handlerpopup/contact.js
$("#downloadAllContacts").click(() => {
        s.showContactDownloadLimitLink = !isNinja(), t(), C(), sendMsgToActiveTab({
          from: POPUP_JS,
          subject: MSG_LIB_DOWNLOAD_CONTACTS,
          data: o()
        })
05EvidenceCODE COMPARE
The code that does this

The content script posts contact-export metadata to Firebase

What it actually does
Readable spreadsheet export and metadata callcontent/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 helpercontent/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) {}
}
06EvidenceTHIRD PARTY LIST
External host receiving the contact-export metadata
  • us-central1-waplugin-34798.cloudfunctions.net

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

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

WhatsApp Phone Number Cookie on wabiz.in

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

This depends on a paired session; an earlier DA run hit the QR login wall and didn't exercise it.

01EvidenceCAUSE EFFECT
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.

02EvidenceFIELD TABLE
Cookie values written for wabiz.in
FieldValueWhy it matters
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.
03EvidenceCODE COMPARE
The code that does this

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

What it actually does
Readable popup cookie writerpopup/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 lookuppopup/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()
}
04EvidenceCODE COMPARE
The code that does this

Manifest permissions allow the cookie write

What it actually does
    "permissions": [
        "storage",
        "cookies",
        "https://wabiz.in/",
        "alarms",
        "identity",
        "identity.email"
    ],
    "host_permissions": [
        "https://wabiz.in/*"
    ],
05EvidenceTHIRD PARTY LIST
Cookie destination
  • wabiz.in

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

Data recipients

wabiz.inus-central1-waplugin-34798.cloudfunctions.net
Updated 17 September 2026loooopmofpoapjmkhommonhhmhhbejao