Is Follower Export Tool safe?

Medium risk

IGFollow is medium risk. Once IGFollow's dashboard reaches its logged-in path, it fetches a tool list from social-tools.converts.workers.dev and stores it. Unauthenticated testing, run three times, saw no request to that host, matching the cookie-gated code.…

Converts Teamv3.3.15Chrome Web Store
47Risk

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

Dashboard loads a remote Cloudflare Workers tool list

Once IGFollow's dashboard reaches its logged-in path, it fetches a tool list from social-tools.converts.workers.dev and stores it.

Unauthenticated testing, run three times, saw no request to that host, matching the cookie-gated code.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You open the IGFollow dashboard while the extension can read Instagram cookies.

The extension did this

The dashboard runs its launch path and requests a remote tools list from a Cloudflare Workers host.

If the required Instagram cookie is missing, the code pauses instead of calling the tool-list request.

Fields involved in the remote tool-list request
  • Remote service
    social-tools.converts.workers.dev

    Shows the outside service contacted when the logged-in dashboard loads its tool list.

  • Requested URL
    https://social-tools.converts.workers.dev

    Shows the exact web address used to retrieve the dashboard's tool list.

  • Returned field
    tools

    The dashboard expects a tools list and stores it for use in the page.

Captured request
GEThttps://social-tools.converts.workers.dev

No request body is present in the code path, and no response body was recorded during dynamic analysis.

The code that does this

The dashboard launch path and remote tool-list fetch

Readable version

Readable launch path checks Instagram cookies before fetching tools

deobfuscated/dashboard.js
launch() {  const e = this;  Lo.MSG.sendEventMessage(Lo.EVENT.GET_COOKIE, {    url: "https://www.instagram.com",    name: "ds_user_id"  }, (function(t) {    void 0 != t ? (e.interface_ins_status_code = -1, e.ig_user_id = t, Lo.MSG.sendEventMessage(Lo.EVENT.GET_COOKIE, {      url: "https://www.instagram.com",      name: "csrftoken"    }, (function(t) {      void 0 != t ? (e.csrtoken = t, e.cfg = {        headers: {          "Content-Type": "application/x-www-form-urlencoded",          "X-CSRFToken": e.csrtoken,          "x-requested-with": "XMLHttpRequest",          "x-instagram-ajax": 1        }      }, e.retriveUserInfo(), e.fetchToolsInfo()) : e.pause()    }))) : (e.pause(), e.interface_ins_status_code = 302, e.loading_status = !1)  }))}

Readable tool-list request stores the returned tools array

deobfuscated/dashboard.js
fetchToolsInfo() {  let e = this;  fetch("https://social-tools.converts.workers.dev").then((function(t) {    t.json().then((function(t) {      e.socialTools = t.tools    }))  })).catch((function(e) {    console.log("Fetch Error :-S", e)  }))}
External host contacted by the dashboard code
    • social-tools.converts.workers.dev

    Cloudflare Workers host used by the dashboard code to retrieve a JSON tools list.

Traffic caveat

During dynamic analysis, opening the dashboard three times produced zero requests to social-tools.converts.workers.dev or to any workers.dev host. The code evidence shows the request behind an Instagram-cookie branch, so the observed no-traffic result is consistent with a dashboard that did not complete logged-in initialization.

Login sends converts.cc cookie to IGFollow backend

Signing in with Google, IGFollow reads the `cid` cookie for converts.cc and sends it with your account ID to `igfollow.converts.cc/parse`.

The POST was confirmed; the code pairs `cid` with `uid`/`is_register` before calling `up_mk_cv`.

Severity
Low unwanted
Type
Unexpected
CWE
CWE-200
Source
Dynamic sandbox
What actually happens
You did this

You sign in to the extension with Google.

The popup button sends a login message to the extension background code.

The extension did this

The extension reads a converts.cc cookie and sends it with your extension account ID.

The send happens only after the login flow returns a valid extension user.

Fields sent by the login cookie-linking call
  • Your extension account ID
    gG7xdpWP0M (illustrative)

    This identifies the account created or used inside the extension.

  • Your converts.cc cookie
    cid_7f3a1b2c9d4e (illustrative)

    This can link your extension account to an existing converts.cc marketing or tracking record.

  • Registration status
    true

    This says whether the login created a new extension account or used an existing one.

Captured request
POSThttps://igfollow.converts.cc/parse
The code that does this

Login completion reads the cookie and calls the backend

Readable version

Popup login method

deobfuscated/popup.js:8028-8033
methods: {  login() {    G().track("LOGIN_CLICK");    const e = this;    e.loading = !0, S.MSG.sendEventMessage(S.EVENT.LOG_IN, {}, (function(e) {}))  }}

Cookie read helper

deobfuscated/background.js:3936-3946
function E(e, t, r) {  chrome.cookies.get({    url: e,    name: t  }, (function(e) {    if (r) {      let t;      void 0 != e && (t = e.value), r(t)    }  }))}

Successful login path calls A(user, false)

deobfuscated/background.js:3961-3970
function S(e, t, r) {  T(e, t).then((e => {    b.MSG.sendEventMessage(b.EVENT.LOGIN_SUCCESS, e), r({      success: !0,      user: e    }), A(e, !1)  }), (n => {    R(n, e, t, r)  }))}

New-account login path calls A(user, true)

deobfuscated/background.js:3972-3994
function R(e, t, r, n) {  switch (e.code) {    case 209:      Parse.User.logOut().then((() => {        S(t, r, n)      }), (e => {        S(t, r, n)      }));      break;    case 101:      O(t, r).then((e => {        b.MSG.sendEventMessage(b.EVENT.LOGIN_SUCCESS, e), n({          success: !0,          res: e        }), A(e, !0)      }), (e => {        R(e, t, r, n)      }));      break;    default:      b.MSG.sendEventMessage(b.EVENT.LOGIN_NOT_SUCCESS, {}, null), console.log("Error: " + e.code + " " + e.message)  }}

Cookie value is sent through the Parse cloud function

deobfuscated/background.js:4002-4011
async function A(e, t) {  console.log("user id: ", e.id), E("https://converts.cc", "cid", (function(r) {    if (console.log("cid:" + r), r) {      let n = {        uid: e.id      };      n["cid"] = r, n["is_register"] = t, Parse.Cloud.run("up_mk_cv", n).then((function(e) {}), (function() {}))    }  }))}

Parse is configured to use the IGFollow backend

deobfuscated/background.js:3813-3823,4012
const n = "https://igfollow.converts.cc";let i = 1 === e ? "https://igfollow.converts.cc/parse" : "http://localhost:1337/parse";const a = {  SERVER_KEY: "LhsTSutjvAbMo7cfu0ejZZxTbIT2LdAuro9G7kuo",  JS_KEY: "FzsCyGBxuXZA8hBoLsNazZoT7Rzk6vEpUhTDH3n6",  SERVER_URL: i};Parse.initialize(b.APP.SERVER_KEY, b.APP.JS_KEY), Parse.serverURL = b.APP.SERVER_URL
Host receiving the cookie-linking request
    • igfollow.converts.cc

    IGFollow backend endpoint that receives Parse Cloud function calls, including the login-time up_mk_cv call.

    • converts.cc

    Cookie domain read by the extension for the cid identifier after login.

Updated 30 September 2026pkafmmmfdgphkffldekomeaofhgickcg