Is WA Self Sender & Easy Sender - Personalized WA Messages & Group Tools safe?

High risk

WA Self Sender & Easy Sender sends WhatsApp message bodies and recipient phone numbers to Aliyun Logs.

When its WhatsApp bulk-send script sends a message, it logs the message text and target recipient through the extension background page. The same log event is enriched with the stored user phone number plus browser, platform, UUID, and version metadata before being posted to an Aliyun Log Service endpoint.

easy-sender-publisherv1.7.8Chrome Web Store
72Risk
Who publishes it

easy-sender-publisher - no other listings under this identity, 3 shared hostnames

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

Publisher
easy-sender-publisher

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.

wasender.zfscrmteam.top
Also called by 1 other listing: wa-download-%E2%80%94-whatsapp-ch
zhuyuntao.cn
Also called by 2 other listings: WA Bulk Message Sender, WARocket Sender:Rocket Sender - WAPI Sender
cdn.waplus.io
Also called by 5 other listings

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

Publishers can request a review.

Findings

WhatsApp Messages Posted to Aliyun Logs

When the WhatsApp send workflow runs, the extension builds a log event from the message text and recipient number, adds the sender's phone number plus browser, platform, UUID, language, version, then posts it to its Aliyun Logs endpoint.

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

You send a WhatsApp message through the extension workflow.

The trigger is the extension's simple or pro send path, not ordinary browsing outside that workflow.

The extension did this

The extension prepares a log event containing the message text and phone numbers, then forwards it to Aliyun Logs.

The event is routed through the background service worker before the SLS logger posts it.

Fields the code places into the Aliyun log event
  • Outgoing message text
    Order update: your appointment is confirmed at 3 PM (illustrative)

    This can reveal the content you asked the extension to send on WhatsApp.

  • Recipient phone number
    +14155550137 (illustrative)

    This identifies which WhatsApp number was targeted by the send workflow.

  • Stored sender phone number
    +442071838750 (illustrative)

    This ties the event back to the WhatsApp account number saved by the extension.

  • Browser and install metadata
    Chrome on Linux, extension version 1.6.69, language en-US (illustrative)

    This adds device and extension context to the same event.

Captured request
POSThttps://extension-us.us-west-1.log.aliyuncs.com/logstores/scrm-web-sender-juzhen/track
Headers
Content-Type
application/x-protobuf
x-log-apiversion
0.6.0
The code that does this

Shipped bundle functions and readable source-map code for the log path

Readable version

Source-map main() function builds logData from contentTmp and phoneNumList[indexCount]

webpack:///./src/content-scripts/content-script.js
async function main(  phoneNumList,  phoneNumSuccessList,  phoneNumFailList,  repeatList,  oldSuccessAndFailList,  indexCount,  content,  mediaType,  minNum,  maxNum,  excelData,  dailySendNums,  sendMessageType,  allDataImg,  allDataVideo,  allDataDocument,  sendButtonValue,  buttonInputValue,  button_radio,  isDeleteMessage,  audio = {}) {  // 检查是否达到发送上限  const { isReachSendLimit, showConfirmTitle } = checkDailySendNums(dailySendNums)  if (isReachSendLimit) {    chrome.storage.local.set({ stopFlag: true, stopFlagSimple: true })    chrome.runtime.sendMessage({      isReachSendLimit: isReachSendLimit,      showConfirmTitle: showConfirmTitle,      stopFlag: true,      stopFlagSimple: true    })    return  }  // 判断用户是否点击了stop按钮  if (    (sendMessageType === 'pro' && !stopFlag) ||    (sendMessageType === 'simple' && !stopFlagSimple)  ) {    // 将用户输入的手机号转化成列表    let phoneNumListLen = phoneNumList.length    if (indexCount < phoneNumListLen) {      // 处理发送内容      let tmpData = dealContentPlaceholder(        // 判断是否为excelData? 处理当前number的content        content,        excelData,        phoneNumList[indexCount],        phoneNumList,        indexCount      )      let contentTmp = tmpData[0]      let isExcelData = tmpData[1]      let isPlaceHolder = tmpData[2]      let isGroupData = await isGroupPhoneNumList(phoneNumList[indexCount])      // console.log('isGroupData' + isGroupData);      let s_source = sendLogDetail(isExcelData, isGroupData)      let isDelete = isDeleteMessage        ? await _sendMessage({            echoDeleteMessage: true,            phone: `${phoneNumList[indexCount]}@c.us`          })        : isDeleteMessage      console.log(isDelete)      let sendStatus = await sendContent(        phoneNumList[indexCount],        contentTmp,        mediaType,        allDataImg,        allDataVideo,        allDataDocument,        sendButtonValue,        buttonInputValue,        button_radio,        audio      )      if (isDelete) {        _deleteMessage(`${phoneNumList[indexCount]}@c.us`)      }      if (sendStatus) {        countSuccess += 1        phoneNumSuccessList.push(phoneNumList[indexCount])        const realPhoneNumSuccessList = await batchGetContactPhone(phoneNumSuccessList)        chrome.storage.local.set({          countSuccess: phoneNumSuccessList.length,          phoneNumSuccessList: realPhoneNumSuccessList,          disabledSendingFlag: false,          stopFlag: false,          stopFlagSimple: false,          isShowContinueBtn: false        })        stopFlagSimple = false        stopFlag = false        chrome.runtime.sendMessage({          countSuccess: phoneNumSuccessList.length,          disabledSendingFlag: false        })        dailySendNums = incrDailySendNumsAndSendMsg(dailySendNums)      } else {        countFail += 1        phoneNumFailList.push(phoneNumList[indexCount])        const realPhoneNumFailList = await batchGetContactPhone(phoneNumFailList)        chrome.storage.local.set({          countFail: phoneNumFailList.length,          phoneNumFailList: realPhoneNumFailList,          disabledSendingFlag: false,          stopFlag: false,          stopFlagSimple: false,          isShowContinueBtn: false        })        stopFlagSimple = false        stopFlag = false        chrome.runtime.sendMessage({          countFail: phoneNumFailList.length,          disabledSendingFlag: false        })      }      //日志301301 日志302301      let eventNum = sendMessageType === 'simple' ? 301301 : 302301      let logData      if (sendMessageType === 'simple') {        logData = {          s_content: contentTmp,          s_source: s_source,          s_min_num: minNum,          s_max_num: maxNum,          s_status: sendStatus ? 1 : 2,          s_target_phone: phoneNumList[indexCount]        }      } else {        logData = {          s_content: contentTmp,          s_source: s_source,          s_attachment: mediaType ? 1 : 2,          s_attachment_type:            mediaType === 'img'              ? 1              : mediaType === 'video'              ? 2              : mediaType === 'doc'              ? 3              : mediaType === 'contact'              ? 4              : '',          s_min_num: minNum,          s_max_num: maxNum,          s_status: sendStatus ? 1 : 2,          s_placeholder: isPlaceHolder ? 1 : 2,          s_button: sendButtonValue ? 1 : 2,          s_target_phone: phoneNumList[indexCount],          s_button_type:            button_radio === 'Link'              ? 2              : button_radio === 'Call'              ? 3              : button_radio === 'Text'              ? 1              : '',          s_button_text: buttonInputValue        }      }      // console.log(eventNum);      // console.log(logData);      sendLog(eventNum, logData)      indexCount += 1      // 发送日志到GA      // if (sendMessageType === 'pro') {      //     await visitor.event("发消息", "发消息-用户手机号-pro", myNumber).send();      // }      // if (sendMessageType === 'simple') {      //     await visitor.event("发消息", "发消息-用户手机号-simple", myNumber).send();      // }      // 获取重复手机号操作      let tmpValues = await getNoRepeatIndex(        indexCount,        phoneNumList,        phoneNumSuccessList,        phoneNumFailList,        repeatList,        oldSuccessAndFailList      )      indexCount = tmpValues[0]      repeatList = tmpValues[1]      chrome.storage.local.set({ repeatList: repeatList })      let continueSendData = getContinueSendData(        phoneNumList,        phoneNumSuccessList,        phoneNumFailList,        repeatList,        oldSuccessAndFailList,        indexCount,        content,        mediaType,        minNum,        maxNum,        excelData,        sendMessageType,        allDataImg,        allDataVideo,        allDataDocument,        sendButtonValue,        buttonInputValue,        button_radio,        isDeleteMessage      )      let retryFailedSendData = getRetryFailedSendData(        phoneNumList,        phoneNumSuccessList,        phoneNumFailList,        repeatList,        oldSuccessAndFailList,        indexCount,        content,        mediaType,        minNum,        maxNum,        excelData,        sendMessageType,        allDataImg,        allDataVideo,        allDataDocument,        sendButtonValue,        buttonInputValue,        button_radio,        isDeleteMessage      )      chrome.storage.local.set({ continueSendData, retryFailedSendData })      // 如果发送的是最后一条消息,那么不用等待      if (indexCount < phoneNumListLen) {        // 睡眠需要等待的时间,每发80条消息休眠3~5min        if ((indexCount - 1) % 80 === 79) {          await sleepBySeconds(180, 300)        } else if (indexCount === 0) {          //第一次发送等待时间设置为0          await sleepBySeconds(0, 0)        } else {          await sleepBySeconds(minNum, maxNum)        }      }      return main(        phoneNumList,        phoneNumSuccessList,        phoneNumFailList,        repeatList,        oldSuccessAndFailList,        indexCount,        content,        mediaType,        minNum,        maxNum,        excelData,        dailySendNums,        sendMessageType,        allDataImg,        allDataVideo,        allDataDocument,        sendButtonValue,        buttonInputValue,        button_radio,        isDeleteMessage,        audio      )    } else {      return new Promise((resolve) => {        setTimeout(function () {          //该部分以后可以做成导出,先注释备用          // alert("一共发送的手机号数量为:" + phoneNumList.length + "\n" + "发送成功的次数为:" + countSuccess + "\n" +          //     "发送失败的次数为:" + countFail + "\n" + "发送失败的电话号码为:" + phoneNumFailList.toString());          chrome.storage.local.set({            stopFlag: true,            stopFlagSimple: true,            anShowWaitSendTip: false,            groupPhoneNumList: []          })          chrome.runtime.sendMessage({            stopFlag: true,            stopFlagSimple: true,            disabledSendingFlag: false          })        }, 2000)        resolve()      })    }  } else {    // console.log("用户终止了content操作");  }}

Source-map sendLog and dealLog functions forward and enrich the event

webpack:///./src/utils/log-util.js
function sendLog(eventType, otherParams) {  chrome.runtime.sendMessage({    type: 'log',    eventType: eventType,    otherParams: otherParams  })}const opts = {  host: 'us-west-1.log.aliyuncs.com',  project: 'extension-us',  time: 0.05,  count: 1,  // 测试  // logstore: 'scrm-user-test'  // 生产  logstore: LOGSTORE}import { EVENT_MAPPING } from '@/const/contant-log.js'const logger = new SlsWebLogger(opts)function dealLog(data) {  let eventType = data.eventType  let otherParams = data.otherParams  // 从local Storage获取用户基本信息,经过简单处理确定sendData  chrome.storage.local.get(    [      'browserInfo',      'platform',      'installTime',      'userPhoneNum',      'firstSendTime',      'uuid',      'version',      'language'    ],    function (res) {      let browserInfo = res.browserInfo !== undefined ? res.browserInfo : ''      let user_agent = browserInfo ? browserInfo.userAgent : ''      let browser_type = browserInfo ? browserInfo.browser : ''      let platform = res.platform !== undefined ? res.platform : ''      let installTime = res.installTime !== undefined ? res.installTime : ''      let phoneNum = res.userPhoneNum      let firstSendTime = res.firstSendTime !== undefined ? res.firstSendTime : ''      let uuid = res.uuid !== undefined ? res.uuid : ''      let version = res.version !== undefined ? res.version : ''      let language = res.language !== undefined ? res.language : ''      let version_current = chrome.runtime.getManifest().version      let eventTypeDesc = eventType === undefined ? null : EVENT_MAPPING[eventType]      let sendData = {        event_source: 3,        event_type: eventType,        event_type_desc: eventTypeDesc,        event_time: Math.round(new Date() / 1000),        install_time: installTime,        s_first_send_time: firstSendTime,        platform,        user_agent,        browser_type,        uuid,        version,        version_current,        language      }      // 如果获取到用户手机号      if (phoneNum !== undefined) {        let PhoneNumber = require('awesome-phonenumber')        let c = PhoneNumber('+' + phoneNum).getRegionCode() // -> 'SE'        let pn = new PhoneNumber(phoneNum.toString(), c)        let region = pn.getRegionCode() ? pn.getRegionCode() : ''        let countryCode = getCountryNameByDomain(region) ? getCountryNameByDomain(region) : ''        sendData.s_user_phone_num = phoneNum        sendData.s_country_code = countryCode        chrome.storage.local.set({ phoneNum, countryCode })      } else {        sendData.s_user_phone_num = ''        sendData.s_country_code = ''      }      // 如果有额外参数,需要修改sendData      if (otherParams) {        for (let key in otherParams) {          sendData[key] = otherParams[key]        }      }      // 发送阿里云日志      logger.send(sendData)    }  )}

Source-map SLS logger turns queued logs into a POST body

webpack:///./node_modules/js-sls-logger-v3/dist/index.js
key: "logger",        value: async function logger(payload = false) {            var arr = payload !== false && payload.length > 0 ? payload : [];            if (arr.length === 0) return;            var url = "https://" + this.project + "." + this.host + "/logstores/" + this.logstore + "/track";            try {                var reqPayload = JSON.stringify({                    __logs__: arr                });                let headers = new Headers({                    "x-log-apiversion": "0.6.0",                    "x-log-bodyrawsize": reqPayload.length                })                if (!this.compress) {                    let blob = new Blob([reqPayload], {                        type: "application/x-protobuf"                    });                    headers.append('Content-Type', "application/x-protobuf")                    fetch(url, {                        method: "POST",                        headers,                        body: blob                    }).then(response => response)                } else {                    headers.append("x-log-compresstype", "lz4")                    var input = Buffer.from(reqPayload);                    var maxOutputSize = lz4.encodeBound(reqPayload.length);                    var output = Buffer.alloc(maxOutputSize);                    var compressedSize = lz4.encodeBlock(input, output);                    output = output.slice(0, compressedSize);                    fetch(url, {                        method: "POST",                        headers,                        body: output                    }).then(response => response)                }            } catch (e) {                console.log(e)            }        }
External destination reached by the logging path
    • extension-us.us-west-1.log.aliyuncs.com

    Receives extension log events through Alibaba Cloud Log Service; the code sets project extension-us, host us-west-1.log.aliyuncs.com, and logstore scrm-web-sender-juzhen.

Where it sends data

Destinations our analysis observed WA Self Sender & Easy Sender - Personalized WA Messages & Group Tools 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.

  • extension-us.us-west-1.log.aliyuncs.comwidely used

    WA Self Sender & Easy Sender - Personalized WA Messages & Group Tools sends data to extension-us.us-west-1.log.aliyuncs.com. A widely used service: 27 other extensions we have analysed send data here.

Updated 30 September 2026khfmfdepnleebhonomgihppncahojfig