Is Autofill Smartly - JobFill safe?
Autofill Smartly - JobFill sends full page text, form field metadata, and visited hostnames to jobfill.ai on user actions.
When a user clicks 'Save Job', the extension captures the full text content and URL of the current page and sends them to jobfill.ai/api/applications/extract. On each autofill event, it also transmits form field labels, names, types, and placeholder text to jobfill.ai/api/labels, and sends the visited hostname to both jobfill.ai/api/events and Google Analytics. Additionally, clicking 'Summarize' sends the full page text to jobfill.ai/api/summary.
Who publishes itJobFill - no other listings under this identity
JobFill - 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
Save Job sends page text and URL to JobFill
Clicking Save Job in JobFill clones the page, extracts title and text with Readability, adds the URL, and sends those to the service worker, which POSTs to jobfill.ai/api/applications/extract.
DA confirmed injection, not the POST body.
What actually happens
You click Save Job in the JobFill sidebar on a page.
The sidebar is rendered by the content script that runs on matching pages.
The extension reads the page's readable text, title, and current URL and sends them to JobFill.
The service worker posts those fields to the application-extraction endpoint.
Fields prepared for the Save Job request
- Readable page textSenior Software Engineer, Platform Team. Build internal tools for application workflows and collaborate with product teams. (illustrative)
This can include the main text from the page where you clicked Save Job, such as a job description or application instructions.
- Page titleSenior Software Engineer - Acme Careers (illustrative)
This identifies the browser page or document title attached to the saved job.
- Current page URLhttps://www.linkedin.com/jobs/view/3987654321/ (illustrative)
This identifies the exact page you submitted through Save Job.
Captured request
No request body was captured during dynamic analysis because the JobFill sign-in flow could not be completed; the shipped service worker posts to this endpoint after receiving the Save Job message.
The code that does this
The Save Job button collects readable page content
Readable content-script Save Job handler
content.jsC = function() { var t = sa(ra().mark((function t() { var n, e, r, i, o, a, s; return ra().wrap((function(t) { for (;;) switch (t.prev = t.next) { case 0: return t.prev = 0, c(!0), l().Notify.info("Saving the job...", { timeout: 2e4 }), n = document.cloneNode(!0), e = new vt.Readability(n), r = e.parse(), t.next = 8, w({ message: "save-job", title: null == r ? void 0 : r.title, textContent: null == r ? void 0 : r.textContent, url: window.location.href }, !0, "", 1e4); case 8: if (!0 !== (null == (i = t.sent) ? void 0 : i.status) || "object" !== na(null == i ? void 0 : i.data)) { t.next = 13; break } return o = i.data, a = o.status, s = o.message, l().Notify["success" === a ? "success" : "failure"](s), t.abrupt("return"); case 13: throw new Error("Invalid response format"); case 16: t.prev = 16, t.t0 = t.catch(0), l().Notify.failure("Failed to save the job"); case 20: return t.prev = 20, c(!1), t.finish(20); case 23: case "end": return t.stop() } }), t, null, [ [0, 16, 20, 23] ]) }))); return function() { return t.apply(this, arguments) }}();Readable Save Job button click
content.jspt.createElement("button", { type: "button", className: "w-full rounded-md bg-indigo-500 px-0 py-2 text-center text-xs font-semibold mb-2 text-white hover:bg-indigo-400 cursor-pointer focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500", onClick: function() { C(), w({ message: "ga-event", event_name: "sw-c-sj" }, !1) }, disabled: u}, u ? "Saving..." : "Save Job")The code that does this
The service worker posts those fields to JobFill
Readable authenticated JobFill client
service-worker.jsvar $n = null, Kn = null, Zn = ["jf_u", "jf_k", "jf_s"], ti = "https://jobfill.ai", ei = new URL(ti).hostname, ni = fn.create({ baseURL: "https://jobfill.ai", withCredentials: !0, timeout: 18e4 });Readable save-job POST branch
service-worker.jsif ("save-job" === t.message) return ni.post("/api/applications/extract", { title: t.title, textContent: t.textContent, url: t.url}).then((function(t) { n({ status: !0, data: t.data })})).catch((function(t) { n({ status: !1 })})), !0;Destination named by the Save Job flow
- jobfill.ai
Receives the Save Job application-extraction request containing the page title, readable text content, and URL.
Autofill sends site hostnames to JobFill and Google Analytics
When you use JobFill's autofill, the extension reads the current website hostname and sends it to JobFill.
The hostname also feeds a Google Analytics page_view event, revealing which site you filled during a signed-in session.
What actually happens
You use Autofill on a website.
The extension sends the current site hostname to JobFill and records it as an analytics page view.
Fields sent by this path
- Website hostnamecareers.example.org
Shows which site you were using when Autofill ran.
- Analytics event namehn
Ties the website hostname to a page-view event for this extension.
- Analytics client ID7f0b47a4-83d0-44b3-8f75-1dd6aef8b6c1
Lets the analytics service group repeated events from the same browser profile.
Captured request
No body or response was recorded in unauthenticated dynamic testing; the shipped handler posts this URL when Autofill reaches the ga-hn path.
Captured request
No live Google Analytics response was recorded in unauthenticated dynamic testing; the shipped handler invokes this endpoint through firePageViewEvent.
The code that does this
The content script sends the hostname and the service worker forwards it
Readable content-script hostname message
content.jscase 16: return Zd.value = !0, rp.value = ru(Zd, rp, _d), ip(), window.self === window.top && w({ message: "ga-hn", hn: window.self.location.hostname }, !1), t.abrupt("return", !1);Readable service-worker hostname handler
service-worker.jsif ("ga-hn" === t.message) { try { u.firePageViewEvent("hn", t.hn), ni.post("/api/events", { hn: t.hn }).catch((function(t) {})) } catch (t) {} return !1}Readable analytics page-view wrapper
service-worker.jskey: "firePageViewEvent",value: (o = c(a().mark((function t(e, n) { var i, o = arguments; return a().wrap((function(t) { for (;;) switch (t.prev = t.next) { case 0: return i = o.length > 2 && void 0 !== o[2] ? o[2] : {}, t.abrupt("return", this.fireEvent("page_view", r({ page_title: e, page_location: n }, i))); case 2: case "end": return t.stop() } }), t, this)}))), function(t, e) { return o.apply(this, arguments)})Destinations reached by the hostname path
- jobfill.ai
Receives the hostname in a POST to /api/events when the ga-hn handler runs.
- www.google-analytics.com
Receives a Measurement Protocol page_view event with the hostname as page_location.
Summarize sends current page text to JobFill
Clicking Summarize in the JobFill sidebar converts the page to visible text and posts that text to JobFill for summarization.
Since the content script runs on all sites, submitted text can come from any page with the sidebar available.
What actually happens
You click Summarize in the JobFill sidebar.
The extension reads visible text from the current page and posts it to JobFill.
Fields sent for summarization
- Page textSenior Product Manager role, responsibilities, requirements, and application questions
Can include the visible content you are reading, editing, or preparing to submit on the active site.
Captured request
The static proof path shows the service worker posts raw_text to this endpoint; no recorded request body is included here.
The code that does this
The sidebar extracts page text and the service worker posts it
Readable Summarize button handler
content.jspt.createElement("button", { type: "button", className: "w-full rounded-md bg-indigo-500 px-0 py-2 text-center text-xs font-semibold mb-2 text-white hover:bg-indigo-400 cursor-pointer focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500", onClick: function() { n(), w({ message: "ga-event", event_name: "sw-c-sm" }, !1) }, disabled: e}, e ? "Summarising..." : "Summarize")Readable text extraction helper
content.jsfunction Lo(t) { return function(t, n = {}, e) { return To(n)(t, e) }(t.documentElement.innerHTML, { wordwrap: !1, selectors: [{ selector: '[style*="display: none"]', format: "skip" }, { selector: '[style*="visibility: hidden"]', format: "skip" }, { selector: "[hidden]", format: "skip" }, { selector: ".hidden", format: "skip" }, { selector: ".d-none", format: "skip" }, { selector: ".invisible", format: "skip" }, { selector: '[aria-hidden="true"]', format: "skip" }, { selector: ".visually-hidden", format: "skip" }] }).trim()}Readable summary message sender
content.jscase 7: return t.next = 9, w({ message: "generate-summary", raw_text: n }, !0, "", 12e4);case 9: if ((r = t.sent).status) { t.next = 13; break } return t.abrupt("return");Readable service-worker summary handler
service-worker.jsif ("generate-summary" === t.message) return Dn(Bn().mark((function e() { var i; return Bn().wrap((function(e) { for (;;) switch (e.prev = e.next) { case 0: return e.prev = 0, e.next = 3, ni.post("/api/summary", { raw_text: t.raw_text }); case 3: i = e.sent, n({ status: !0, data: i.data }), e.next = 11; break; case 7: e.prev = 7, e.t0 = e.catch(0), n({ status: !1, message: "Failed to generate summary" }); case 11: case "end": return e.stop() } }), e, null, [ [0, 7] ])})))(), !0;Destination reached by the summarize path
- jobfill.ai
Receives raw page text in POST requests to /api/summary.
+1 more finding not shown
Where it sends data
Destinations our analysis observed Autofill Smartly - JobFill 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.
- www.google-analytics.comwidely used
Autofill Smartly - JobFill sends data to www.google-analytics.com. A widely used service: 388 other extensions we have analyzed send data here.
- jobfill.ai
Autofill Smartly - JobFill sends data to jobfill.ai. No other extension we have analyzed sends data here.