Is Premium Sender Plus safe?
Premium Sender Plus is high risk. Premium Sender Plus's content script fetches selector JSON from premiumsenderplus.app on WhatsApp Web. The JSON has CSS selectors for chat titles, avatars, messages, media, and controls, used as config. The server can retarget elements.…
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Server-controlled WhatsApp DOM selectors
Premium Sender Plus's content script fetches selector JSON from premiumsenderplus.app on WhatsApp Web.
The JSON has CSS selectors for chat titles, avatars, messages, media, and controls, used as config.
The server can retarget elements.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
You open WhatsApp Web with Premium Sender Plus installed.
The extension retrieves a server-provided map of WhatsApp page selectors and uses it to target page elements.
The selector map is requested by the page bundle and fetched by the content script from premiumsenderplus.app.
The endpoint returns JSON selector configuration; no request body is sent for this GET request.
- Content-Type
- application/json
- Main WhatsApp panel#main
Tells the extension where the active WhatsApp conversation area is on your page.
- Chat title selectorsheader ._ao3e, [data-testid='conversation-info-header-chat-title'], [data-testid='author'], [data-testid='chat-subtitle']
Lets the configuration point features at the chat title shown in your WhatsApp conversation.
- Message selectorsmessage-in, .message-out, [data-testid='conversation-panel-messages'] [data-testid^='conv-msg']
Lets the configuration identify incoming and outgoing message elements on your chat page.
- Status media selectors[data-animate-status-viewer="true"] img[src^="blob"]
Lets the configuration point download features at status images and videos displayed in WhatsApp Web.
- Send control selectors[data-icon="send"],[data-icon="wds-ic-send-filled"]
Lets the configuration identify the send button used by message automation features.
The page bundle requests selectors; the content script fetches them from the server
Deobfuscated page bundle dispatches the selector request and stores the response
deobfuscated/page.min.js(0, e.useEffect)((() => { const e = "dom-".concat(Math.random()); a.once(e, (e => { e && c(e) })), window.dispatchEvent(new CustomEvent("pws::get-dom-selectors", { detail: { name: e } }))}), []), (0, e.useEffect)((() => { AS.set({ dom_selectors: l })}), [l])Deobfuscated page bundle consumes server-supplied selectors in WhatsApp features
deobfuscated/page.min.jse.blur_contact_names ? yw("blur_contact_names", rk(l.enhancements_mainchatclass_chattitle, l.enhancements_sidechatclass_chattitle)) : bw("blur_contact_names"), e.blur_contact_photos ? yw("blur_contact_photos", rk(l.enhancements_sidechatclass_chatavatar, l.enhancements_mainchatclass_chatavatar)) : bw("blur_contact_photos"), e.blur_recent_messages ? yw("blur_recent_messages", rk(l.enhancements_sidechatclass_chatsecondary)) : bw("blur_recent_messages"), e.blur_conversation_messages ? yw("blur_conversation_messages", rk(l.enhancements_messageclass_msg)) : bw("blur_conversation_messages"), e.pin_unread_chats ? (Pw(), window[ft].Chat.off("change:unreadCount", Pw), window[ft].Chat.on("change:unreadCount", Pw)) : (window[ft].Chat.where().filter((e => e.pin)).filter((e => window.pws_pinned_chats.includes(e.id.user))).map((e => e.pin = 0)), window.pws_pinned_chats = [], window[ft].Chat.off("change:unreadCount")), Nw(), window[ft].Chat.off("change:active"), window[ft].Chat.on("change:active", (() => Lw(e, n, l))), Lw(e, n, l)- premiumsenderplus.app
Receives the selector-configuration GET request and returns JSON used to target WhatsApp Web elements.
Install-time IP lookup sent to ip-api.com
We observed Premium Sender Plus make an install-time GET request to ip-api.com/json when it had no stored device name.
This lets ip-api.com infer your IP address; the extension uses the returned country code to set its default language.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You install the extension and first-run setup begins.
The extension contacts a geolocation service before choosing its default language.
Observed during dynamic analysis as an install-time GET request; the response contained a countryCode field.
- Your IP address198.51.100.24 (illustrative)
The remote geolocation service receives the network address your browser uses at install time.
- Country codeUS
The returned country code is used to choose the extension language.
- Network providerExampleNet, New York (illustrative)
The service can return city and provider details associated with the connection.
Install handler that performs the geolocation lookup
Readable install handler excerpt
deobfuscated/background.min.jschrome.runtime.onInstalled.addListener(function() { var t = s(o().mark((function t(e) { var r, n; return o().wrap((function(t) { for (;;) switch (t.prev = t.next) { case 0: return t.next = 2, p({ device_name: "" }); case 2: if (r = t.sent, "" !== r.device_name) { t.next = 10; break } return t.next = 7, Promise.all([fetch("http://ip-api.com/json").then((function(t) { return t.json() })), fetch("/countries.json").then((function(t) { return t.json() }))]).then((function(t) { var e = c(t, 2), r = e[0], n = e[1]; if ("AE" === r.countryCode) return "en"; var i = n.find((function(t) { return t.alpha2 === r.countryCode })); if (!i) return "en"; var o = (i.languages ? i.languages[0] : "en").split("_")[0]; return h[o] ? o : "en" })).catch((function() { return "en" })); } }), t) })));});- ip-api.com
Receives the install-time geolocation lookup and returns country/location metadata.
License check posts phone and license details
Premium Sender Plus validates a license by combining the license key, device code, extension version, device name, and WhatsApp number, wrapping it with embedded AES constants, and posting it to premiumsenderplus.app/mv3/get-license-1.php.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-319
- Source
- Dynamic sandbox
You validate or reuse a Premium Sender Plus license.
The extension sends license, device, version, and WhatsApp number fields to its API.
- License keyPSP-8F42-2026-91AC (illustrative)
This identifies the subscription credential being validated.
- Device codeB-1782148895331 (illustrative)
This links the license check to a specific browser or device record.
- Extension version1.1.79.46
This tells the API which Premium Sender Plus build you are running.
- Device nameChrome-Linux-Workstation (illustrative)
This is the stored device name sent with the license check.
- WhatsApp number+15551234567 (illustrative)
This ties the license check to the WhatsApp account number loaded by the extension.
The source posts a FormData field named encData to this endpoint; no live request body was recorded in verification evidence.
License validation request and embedded AES constants
Readable license request
deobfuscated/popup.min.jssA = function() { var e = t(a().mark((function e(n, t, i, r) { var o, c, s, l, d; return a().wrap((function(e) { for (;;) switch (e.prev = e.next) { case 0: return o = chrome.runtime.getManifest().version, e.prev = 1, c = { license_key: n, device_code: t, version: o, device_name: i, mobile: r }, s = gA(JSON.stringify(c)), e.next = 6, nA("".concat(tA, "/get-license-1.php"), "POST", { encData: s }); case 6: return l = e.sent, e.next = 9, hA(null == l ? void 0 : l.data); case 9: if (!(d = e.sent)) { e.next = 12; break } return e.abrupt("return", JSON.parse(d)); } }), e, null, [[1, 14]]) }))); return function(a, n, t, i) { return e.apply(this, arguments) }}();Readable request helper and AES helpers
deobfuscated/popup.min.jsnA = function() { var e = t(a().mark((function e(n, t, i) { var r, o, c, s; return a().wrap((function(e) { for (;;) switch (e.prev = e.next) { case 0: for (c in r = { method: t, redirect: "follow" }, o = new FormData, i) o.append(c, i[c]); return r.body = o, "GET" === t && delete r.body, e.next = 7, fetch(n, r).then((function(e) { return e.json() })); case 7: return s = e.sent, e.abrupt("return", s); case 9: case "end": return e.stop() } }), e) }))); return function(a, n, t) { return e.apply(this, arguments) }}(),tA = "https://premiumsenderplus.app/mv3";mA = "abc123abc123abc123abc123abc123ab",pA = "a1b2c3d4e5f6g7h8",hA = function(e) { if (e) { var a = cL().enc.Utf8.parse(mA), n = cL().enc.Utf8.parse(pA); return cL().AES.decrypt(e, a, { iv: n, padding: cL().pad.Pkcs7, mode: cL().mode.CBC }).toString(cL().enc.Utf8) }},gA = function(e) { if (e) { var a = cL().enc.Utf8.parse(mA), n = cL().enc.Utf8.parse(pA); return cL().AES.encrypt(e, a, { iv: n, padding: cL().pad.Pkcs7, mode: cL().mode.CBC }).toString() }};- premiumsenderplus.app
Receives the encrypted license-validation form field for the extension API.
+2 more findings not shown