Is Octopus - All-in-One LinkedIn Automation safe?
Octopus CRM is high risk. When the LinkedIn lead-sync path runs, the extension reads contact details from LinkedIn Voyager and sends the lead record (email, phone, profile site, name, company site) to Dripify's shared leads email API. No request body was captured.…
Who publishes itOctopus CRM - no other listings under this identity
Octopus CRM - no other listings under this identity
What this publisher told the store about itself, and the other listings that told it the same thing.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
LinkedIn contact details are posted to Dripify
When the LinkedIn lead-sync path runs, the extension reads contact details from LinkedIn Voyager and sends the lead record (email, phone, profile site, name, company site) to Dripify's shared leads email API.
No request body was captured.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You start the LinkedIn lead-sync workflow for a profile.
The code path is tied to the extension's getSyncLeadData action and requires the authenticated campaign workflow.
The extension gathers LinkedIn contact details and sends the lead record to Dripify.
The source constructs a JSON POST to the shared leads email API.
- Lead email addressalex.chen@example.com (illustrative)
This directly identifies the LinkedIn lead being synced.
- Lead phone number+1 415 555 0137 (illustrative)
This can identify and contact the lead outside LinkedIn.
- Profile websitehttps://alexchen.example (illustrative)
This adds external profile or business context to the synced lead.
- LinkedIn profile IDACoAADeF123B456c789D (illustrative)
This ties the lead record back to a specific LinkedIn profile.
No captured response body was recorded for this authenticated campaign path.
- Authorization
- Bearer <redacted>
Contact fields are read from LinkedIn and then posted to Dripify
Readable contact-field extractor
assets/action-content.jsfunction i(e) { var e = e?.data?.identityDashProfilesByMemberIdentity?.elements; return Array.isArray(e) && 0 !== e.length ? { emailAddress: (e = e[0]).emailAddress?.emailAddress, websites: function(e) { e = e.websites; return Array.isArray(e) && 0 !== e.length ? e.map(e => ({ type: { "com.linkedin.voyager.identity.profile.StandardWebsite": { category: e.category } }, url: e.url })) : [] }(e), phoneNumbers: function(e) { e = e.phoneNumbers; return Array.isArray(e) && 0 !== e.length ? e.filter(e => e?.phoneNumber?.number).map(e => ({ type: e.type, number: e.phoneNumber.number })) : [] }(e) } : {}}Readable lead-sync handler
assets/action-content.js"getSyncLeadData" == o.action && (n = r.then(function(e) { return async function(e, t) { var n = {}, i = await p(e), r = i.elements[0], i = (n.FIRST_NAME = i, n.COMPANY = await h(e), n.EMAIL = await d(e, t), r.profilePositionGroups.elements); return i.length && i[0].companyUrn && (e = i[0].companyUrn.replace("urn:li:fsd_company:", ""), n.COMPANY_WEBSITE = await g(e, t).catch(() => ({}))), { leadData: n, leadId: r.entityUrn.substring(19) } }(o.id, e).then(a)}))Readable Dripify sender
main-es2018.8479c1dfcb59ff03ea0b.jssendDripifyRequest(t) { var e = this; return yg(function*() { let n = yield e.appContext.currentUser.getIdToken(); return e.http.request(t.method, "https://app.dripify.com/api" + t.url, { responseType: "json", body: t.isJson ? t.params : null, params: t.isJson ? null : t.params, headers: { Authorization: "Bearer " + n } }).toPromise() })()}syncAndFindEmail(t, e) { var n = this; return this.httpUtils.sendDripifyRequest({ url: "/v1/shared/leads/email", method: "POST", params: t, isJson: !0 }).catch(function() { var i = yg(function*(i) { return i.error && i.error.message && "OUT_OF_VERIFY_EMAIL_CREDITS" === i.error.message ? (yield n.homepageService.sendHomepageEvent(n_.FORCE_REFRESH_EMAIL_FINDER_CREDITS), n.forceStopProcessing(), !1) : e >= 3 ? (n.forceStopProcessing("Unpredicted errors", "Please contact support"), !1) : (yield e_.later(1e4), n.syncAndFindEmail(t, ++e)) }); return function(t) { return i.apply(this, arguments) } }())}- app.dripify.com
Receives the JSON lead record at /api/v1/shared/leads/email.
- www.linkedin.com
Supplies profile and contact data used to build the lead record.
LinkedIn Recruiter search URLs sent to Dripify API
Starting Octopus's Send to CRM flow from a LinkedIn Recruiter Talent search posts the search URL and Recruiter context to app.dripify.com.
Not captured dynamically; the test session couldn't authenticate Recruiter and Octopus CRM together.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You start the Octopus Send to CRM workflow from a LinkedIn Recruiter Talent search.
The popup copies the current search URL into the selection data before sending the request to the extension workflow.
The extension sends that Recruiter search context to Dripify to build the search URL used for profile selection.
The code path is specific to Talent search pages rather than every LinkedIn page.
- LinkedIn Recruiter search URLhttps://www.linkedin.com/talent/search/results/people?keywords=account%20executive&origin=GLOBAL_SEARCH_HEADER
Shows the Recruiter search page you are using and can include search keywords, filters, project context, and result-page state.
- Recruiter contracturn:li:contract:82374651
Connects the request to the Recruiter account context active in the LinkedIn tab.
- Hiring project state[{"state":"IN_REVIEW","count":25}]
Adds project-specific Recruiter state when the Talent URL points at an all-candidates project view.
The shipped code expects a JSON response with a url property and returns that value to the profile-selection workflow.
- Authorization
- Bearer <redacted>
The popup selection flow and Dripify request construction
Readable request helper builds the Dripify API call
deobfuscated/main-es2018.8479c1dfcb59ff03ea0b.jssendDripifyRequest(t) { var e = this; return yg(function*() { let n = yield e.appContext.currentUser.getIdToken(); return e.http.request(t.method, "https://app.dripify.com/api" + t.url, { responseType: "json", body: t.isJson ? t.params : null, params: t.isJson ? null : t.params, headers: { Authorization: "Bearer " + n } }).toPromise() })()}Readable selection method posts the Recruiter URL fields
deobfuscated/main-es2018.8479c1dfcb59ff03ea0b.jsgetSearchUrl(t, e) { var n = this; return yg(function*() { let i, r = t.selectionType.toLowerCase(); if (r.includes("profile") || r.includes("mynetwork")) { let i = n.selectionTypeConfigFactory.getSelectionTypeConfig(t.selectionType); return yield i.composeUrlFunction({ url: t.url, params: null, tabId: e }) } t.selectionType == ZS.RECRUITER_TALENT_PEOPLE && (i = (yield e_.sendTabMessage(n_.GET_TALENT_ME, e, { headers: n.appContext.headers })).contract); const s = new URL(t.url).pathname.split("/"); let o; return t.selectionType === ZS.RECRUITER_TALENT_PEOPLE && "all" === (s.length > 5 ? s[5] : null) && (o = yield e_.sendFirstTabMessage(n_.GET_TALENT_HIRING_PROJECTS, { headers: n.appContext.headers, contract: i, projectId: s[3] })), (yield n.httpUtils.sendDripifyRequest({ method: "POST", url: "/searches/url", isJson: !0, params: { url: t.url, contract: i, hiringStates: o } })).url })()}Readable popup submit handler starts the selection workflow
deobfuscated/main-es2018.8479c1dfcb59ff03ea0b.jssendToCRM() { if (!this.selectForm.valid) return; let t = {}; t.url = this.searchContext ? this.searchUrl : null, t.selectionType = this.searchUrlService.determineSelectionType(this.searchUrl), t.profilesToSelect = this.profilesToSelect > 0 ? this.profilesToSelect : 100, t.selectedCampaign = this.selectedCampaign, t.selectedAction = this.selectedAction, this.helperService.showSelectModal(), e_.sendMessage(n_.START_SELECT, { data: t })}- app.dripify.com
Receives the POST to /api/searches/url containing the LinkedIn Recruiter search URL fields prepared by the extension code.
What it can do
Permissions this extension asks for, as declared in version 3.7.19. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to. The current listed version is 3.7.17, which we have not unpacked yet.
Read and change your data on linkedin.com
https://linkedin.com/* and 1 more
Read and change your data on api.octopuscrm.io
https://api.octopuscrm.io/*
Read and change your data on hooks.zapier.com
https://hooks.zapier.com/*
Read and change your data on octopuscrm-io.firebaseapp.com
https://octopuscrm-io.firebaseapp.com/*
Read and change your data on make.com
https://*.make.com/*
Read and change your data on cdnjs.cloudflare.com
https://cdnjs.cloudflare.com/ajax/libs/raphael/*
Read and change your data on firebaseio.com
https://*.firebaseio.com/*
Read and change your data on www.googleapis.com
https://www.googleapis.com/*
Read and change your data on www.gstatic.com
https://www.gstatic.com/*
Read and change your data on apis.google.com
https://apis.google.com/*
Read and change your data on us-central1-test-proj-7d39d.cloudfunctions.net
https://us-central1-test-proj-7d39d.cloudfunctions.net/*
See the address and title of every tab you have open
tabs
Show you desktop notifications
notifications
Read and change your full browsing history
history
Run its own code inside the pages you visit
scripting
Run hidden pages in the background
offscreen