Is InsTF - Instagram follower & unfollower tracker safe?
InsTF sends the signed-in user's Google email address and Instagram profile statistics to Mixpanel on account sign-in and follower-tracking task execution.
When a user signs in via Google OAuth, the extension forwards their email address and membership status to Mixpanel's People API, linked to a persistent UUID stored in chrome.storage.sync. Each time the user runs a follower-tracking task against their own Instagram account, it also sends their Instagram username, follower count, following count, and media count to Mixpanel. Task lifecycle events — including the target Instagram account ID and task type — are transmitted to api-js.mixpanel.com on task start and completion.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Google email and Instagram task data sent to Mixpanel
After Google sign-in and follower-tracking actions, code shows the extension attaches your email, membership fields, Instagram stats, and download counts to a Mixpanel profile/event.
Captured POSTs only showed page-view/profile analytics.
You sign in with Google or start an Instagram follower-tracking task.
Download actions from scraped Instagram results also trigger analytics events.
The extension adds account, profile, task, and count fields to Mixpanel profile updates or event calls.
The sensitive sign-in and task fields are shown in code; the available captured Mixpanel traffic did not include those fields.
| Field | Value | Why it matters | |
|---|---|---|---|
Analytics identifier | 6fce7a7d-4c0e-4e5b-9bc6-6b0dc81db0e2 (illustrative) | Lets Mixpanel tie future sign-in, task, and download events to the same browser profile. | |
Google account email | alex.rivera@example.com (illustrative) | Identifies the Google account used to sign in to the extension. | |
Membership record | membership: Pro; is_yearly: true; starts_at: 2026-01-15T00:00:00.000Z; ends_at: 2027-01-15T00:00:00.000Z (illustrative) | Adds subscription context to the same analytics profile. | |
Instagram profile statistics | username: alexruns; media_count: 92; follower_count: 1842; following_count: 730; profile_url: https://www.instagram.com/alexruns/ (illustrative) | Links your Instagram username and follower counts to the analytics profile when you track your own account. | |
Task target and settings | target: 17841400001234567; actionType: getProfile; loopType: follower; total: 250 (illustrative) | Shows which Instagram account or list the extension was asked to process and how the task was configured. | |
Downloaded contact counts | filter: email; total: 250; emailCount: 18; phoneCount: 4 (illustrative) | Summarizes how many scraped profiles had email or phone fields in the downloaded result set. |
Mixpanel setup, profile updates, task events, and download events
async function MV() {
let t = (await it.storage.sync.get("MIXPANEL_USER_ID")).MIXPANEL_USER_ID;
return t || (t = globalThis.crypto.randomUUID(), await it.storage.sync.set({
MIXPANEL_USER_ID: t
})), t
}const Vk = {
InsTF: {
mixpanel_token: "8f728f9dda62790d6831ca89119dee88",
sentry_DSN: "https://9d1a7261a888a4a542c01ad9396072b8@o4507079421394944.ingest.us.sentry.io/4507079424081920"
}
},
qk = Vk.InsTF.mixpanel_token;
async function XG() {
try {
_r.init(qk, {
debug: !1,
persistence: "localStorage"
}), _r.register({
ext_name: "InsTF",
ext_version: "6.1.11"
});
const e = await MV();
_r.identify(e), _r.people.set_once({
"First Seen": new Date().toISOString()
})
} catch (e) {
console.error("Failed to initialize Mixpanel:", e)
}
}
XG();async function a() {
try {
o.value = !0;
const w = await nA("launch-web-auth-flow", {
url: n.href
}),
b = new URL(w.redirectedTo),
E = new URLSearchParams(b.hash.substring(1)),
{
data: T,
error: k
} = await s.auth.signInWithIdToken({
provider: "google",
token: E.get("id_token") || ""
});
if (k) throw k;
{
fs("signInWithGoogle", T.user);
const S = T.user;
await l({
id: S.id,
email: S.email,
full_name: S.user_metadata.full_name
}), ["InsC", "InsGrow", "InsFo"].includes("InsTF") && await u()
}
} catch (w) {
fs("signInWithGoogle catch error", w, it.runtime.lastError)
} finally {
o.value = !1
}
}
async function l(w) {
const {
data: b,
error: E
} = await s.from("InsTF").upsert({
...w
}, {
onConflict: "id"
}).select().single();
E && (console.error(`createOrUpdateSupabaseUser error: ${JSON.stringify(E)}`), s.auth.signOut(), lt.value = {}), fs("createOrUpdateSupabaseUser", b), lt.value = b, b.created_at || await s.from("InsTF").update({
created_at: new Date().toISOString()
}).eq("id", b.id), _r.people.set({
email: b.email,
membership: b.membership,
is_yearly: b.is_yearly,
starts_at: b.starts_at,
ends_at: b.ends_at
})
}Rt(async () => {
const g = PV(),
p = g.uuid;
r.value = (await it.storage.local.get(p))[p], await d(l.value);
async function m() {
const x = Wn.getMyId();
if (!x) return _r.track("Not Login", {
profileId: x
}), !1;
const y = (await it.storage.local.get("trackMySelfInfo")).trackMySelfInfo || {};
if (x !== y.id) {
const w = await Wn.getProfile(x);
await it.storage.local.set({
trackMySelfInfo: {
id: w.id,
username: w.username
}
}), y.id = w.id, y.username = w.username
}
return r.value.username === y.username
}
async function _() {
return await m() ? (n.value = !0, await Wn.getProfile(Wn.getMyId())) : await Wn.getProfile(r.value.username, "username")
}
if (!r.value.target && r.value.username) try {
const x = await _();
r.value.target = x.id, r.value.profile = x, o.value.unshift(p), a.value.unshift(r.value), await it.storage.local.set({
[p]: r.value,
[l.value]: [...o.value]
})
} catch (x) {
Gp(x, {
...r.value,
isTrackMySelf: n.value
});
return
}
if (fs("trackTask", r.value), n.value) {
const x = r.value.profile;
_r.people.set({
username: x.username,
media_count: x.media_count,
follower_count: x.follower_count,
following_count: x.following_count,
profile_url: x.profile_url
})
}
_r.track("Task Start", {
...r.value
}), c.value = u.value.length === 0, g.isFirstTrack && (c.value = !0)
});
async function f() {
r.value.isCompleted = !0, await it.storage.local.set({
[r.value.uuid]: r.value
}), await d(l.value), _r.track("Task Completed", {
...r.value
})
}function c(g) {
const p = ["email", "phone"].includes(g) ? l(g) : r.items;
a(p, n.value), _r.track("Download", {
target: r.target,
loopType: r.loopType,
actionType: r.actionType,
format: n.value,
filter: g,
total: r.items.length,
emailCount: p.filter(m => m.email).length,
phoneCount: p.filter(m => m.phone).length
})
}
function u() {
a(r.items, n.value), _r.track("Download", {
target: r.target,
loopType: r.loopType,
actionType: r.actionType,
format: n.value,
total: r.items.length
})
}
function h() {
if (d.value) {
const g = NV(r.items);
a(g, n.value, `${i.value}-distinct-${g.length}`), _r.track("Download", {
target: r.target,
loopType: r.loopType,
actionType: r.actionType,
format: n.value,
total: g.length
})
} else u();
f.value = !1
}- api-js.mixpanel.com
Mixpanel analytics API receiving profile updates and tracked events from the extension code.
- o4507079421394944.ingest.us.sentry.io
Sentry error-reporting endpoint configured next to the Mixpanel token; not the destination for the Mixpanel profile and task events in this claim.