Is Api4Com - Extensão para Navegadores safe?
Api4Com is high risk. Starting a call from the extension dialer makes the popup prepare the contact, add the SIP username and Api4Com access token, and post the call payload to Api4Com, including the target phone number and any CRM metadata on the contact.…
Who publishes itAPI4COM TECNOLOGIA E SERVICOS LTDA - 1 other listing from the same operator, none carrying a finding
API4COM TECNOLOGIA E SERVICOS LTDA - 1 other listing from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
1 other listing published from this account, 7k+ users between them, none of them carrying a finding.
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.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Call initiation posts phone and CRM metadata to Api4Com
Starting a call from the extension dialer makes the popup prepare the contact, add the SIP username and Api4Com access token, and post the call payload to Api4Com, including the target phone number and any CRM metadata on the contact.
You start a call from the Api4Com popup or an injected dialer contact.
The extension posts the target phone number, SIP extension username, access token, and contact metadata to Api4Com.
| Authorization | Bearer <redacted> |
| Field | Value | Why it matters | |
|---|---|---|---|
Target phone number | +55 11 91234-5678 (illustrative) | Identifies the number the extension asks Api4Com to call. | |
SIP extension username | sip-user-123 (illustrative) | Links the call request to the configured phone extension account. | |
Api4Com access token | eyJhbGciOiJIUzI1NiJ9.redacted | Authorizes the extension session used for the dialer API call. | |
CRM gateway | hubspot | Shows which CRM integration produced the selected contact. | |
Contact URL | https://app.hubspot.com/contacts/123/contact/456/view (illustrative) | Keeps the CRM page associated with the outgoing call request. | |
CRM entity IDs | {"contact":"456"} (illustrative) | Carries CRM-specific identifiers such as contact, deal, company, ticket, or lead IDs. |
Contact preparation and /dialer POST
prepareContact(t) {
if (!this.extension) return !1;
if (!this.extension.username) return !1;
const e = {
...t
};
return e.data || (e.data = {}), e.data.extension = this.extension.username, e.metadata || (e.metadata = {}), this.token && this.token.id && (e.metadata.api4comAccessToken = this.token.id), e
},sendCallToAPI({
data: {
phone: t,
extension: e
},
metadata: n
}) {
const r = {
phone: t,
extension: e,
metadata: n
};
return this.$store.dispatch("integrationCall", r).then(r => (this.isDebug && console.info("Api4Com > ContactDialer > sendCallToAPI >", t, e, n, r), r)).catch(t => {
this.isDebug && console.error("Api4Com > ContactDialer > sendCallToAPI >", t.message), 422 === t.statusCode && "InvalidPhoneNumber" === t.name && this.toast.error(chrome.i18n.getMessage("webphoneClickToCallInvalidNumber")), 401 === t.statusCode && (this.toast.error(chrome.i18n.getMessage("mainErrorExpiredToken")), setTimeout(() => {
document.location.reload()
}, 1e4)), 402 === t.statusCode && this.toast.error(chrome.i18n.getMessage("webphoneCallBlockedNoMinutes")), 403 === t.statusCode && "CallBlockedByUserStatus" === t.name && this.toast.error(chrome.i18n.getMessage("webphoneCallBlockedUserNotActive")), 503 === t.statusCode && this.toast.error(chrome.i18n.getMessage("webphoneCallTemporarilyUnavailable"))
})
},function Qm({
commit: t,
state: e
}, n) {
return Fm.configToken(e.token.id), Fm.post("/dialer", n).then(({
data: t
}) => Promise.resolve(t)).catch(e => (401 === e.statusCode && zm(t), Promise.reject(e)))
}- api.api4com.com
Api4Com API host receiving /dialer requests containing the call target, SIP extension username, token metadata, and CRM context.
Clipboard Text Read During Webphone Paste
Pasting into the webphone dialer makes the handler read clipboard text, strip it to dialable characters, and feed them to the dialpad.
The extension requests clipboard-read; testing saw no outbound transmission of clipboard contents.
You paste text into the extension's webphone dialer.
The listener is attached when the webphone component mounts.
The extension reads the current clipboard text and uses the dialable characters as dialpad input.
Dynamic analysis confirmed the paste listener and did not observe clipboard contents being sent over the network.
| Field | Value | Why it matters | |
|---|---|---|---|
Current clipboard text | Client Ana +55 (11) 91234-5678 ext #42 (illustrative) | Clipboard text is read on paste in the dialer. That can include more context than the phone number ultimately dialed. | |
Dialable characters | +5511912345678#42 (illustrative) | After reading the clipboard, the extension keeps numbers and phone-control characters for dialing. | |
Clipboard-read permission | clipboardRead | The installed extension is granted permission to read clipboard text in its own extension pages. |
Paste listener and clipboard read in the shipped popup bundle
function dO(t) {
return t.replaceAll(/[^0-9+*#]/g, "")
}mounted() {
this.$nextTick(() => {
this.extension && !0 !== this.extension.external && (this.checkMicrophonePermission().then(() => {
this.initialize().then(() => {
this.startDebug(), this.userAgentStatus(), this.applyVolumes(), this.emitter.emit("refresh-media-devices"), dispatchEvent(new Event("load"))
})
}), this.addListenerToPaste())
})
}async pasteEventListener() {
navigator.clipboard.readText().then(t => {
const e = dO(t);
this.isDebug && console.info("Api4Com > Webphone > clipboard paste >", e), this.webphone && this.webphone.getDialpad() && e.split("").forEach(t => {
this.webphone.getDialpad().dial(t, !1)
})
}).catch(t => {
this.isDebug && console.info("Api4Com > Webphone > error clipboard paste >", t.message), this.toast.error(gO)
})
}
addListenerToPaste() {
document.addEventListener("paste", this.pasteEventListener)
}
removeListenerToPaste() {
document.removeEventListener("paste", this.pasteEventListener, !1)
}