Is Jobscan: Job Search Tracker safe?

Medium risk

Jobscan is medium risk. When the extension checks whether you're logged in, it sends your browser user agent, which reveals browser version, OS, and platform, in the request URL to api.jobscan.co/user/valet.…

Jobscanv2.2.10Chrome Web Store
52Risk
Who publishes it

Jobscan - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Jobscan
Declared legal entity
Jobscan
Registered address
4616 25TH AVE NE #388, Seattle, WA 98105, US
Registered contact
Nick Moline

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

Publishers can request a review.

Findings

User agent sent to Jobscan validation API during login checks

When the extension checks whether you're logged in, it sends your browser user agent, which reveals browser version, OS, and platform, in the request URL to api.jobscan.co/user/valet.

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

The extension is installed or the popup requests a login check.

The extension did this

The extension reads the browser user agent and includes it in the validation request URL.

Captured request
GEThttps://api.jobscan.co/user/valet?device=navigator.userAgent
Fields in the request
  • Browser user agent
    Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (illustrative)

    Identifies browser version, operating system, and platform context that can help distinguish a device.

Observation

Dynamic analysis confirmed that the code path reads navigator.userAgent and sends it to the Jobscan validation endpoint during install and popup login checks.

A remote config file tells Jobscan which page elements to scrape on job sites

Jobscan fetches a JSON config from static.jobscan.co listing CSS selectors it uses to read job title, company, salary, and description on Indeed, LinkedIn, Glassdoor, and Handshake.

We observed a live 200 response returning this config.

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

You open a job listing on Indeed, LinkedIn, Glassdoor, or Handshake with Jobscan installed.

The content script activates on any page matching those four domains.

The extension did this

The extension fetches a config file from its own server that names the exact page elements to read.

Because the targets live on a server Jobscan controls, they can change without a new extension release.

Captured request
GEThttps://static.jobscan.co/extension/job-sites.json

HTTP 200, 5,613-byte JSON body listing per-site CSS selectors for Indeed, LinkedIn, Glassdoor, and Handshake.

Page fields the remote config points the content script at (Indeed selectors shown)
  • Job title selector
    .jobsearch-JobInfoHeader-title

    Where on the page the extension reads the job title text.

  • Company name selector
    [data-testid="inlineHeader-companyName"] span a

    Where on the page the extension reads the employer's name.

  • Job description selector
    div#jobDescriptionText

    Where on the page the extension reads the full posting text.

  • Salary selector
    #salaryInfoAndJobType > span

    Where on the page the extension reads listed pay or salary range.

  • Tracker-button anchor
    #jobsearch-ViewJobButtons-container

    Element the extension attaches its own Save/Scan buttons next to.

What's stored on your device

The fetched selector list is cached locally for 12 hours before the extension re-fetches it from static.jobscan.co.

Location
chrome.storage.local keys "jobSites" and "jobSitesTimestamp"
Contents
{  "jobSites": "[{\"id\":1,\"label\":\"Indeed\",\"url_pattern\":\"indeed.com\",\"dom_selectors\":{\"job_title\":\".jobsearch-JobInfoHeader-title\",\"company_name\":\"[data-testid=\\\"inlineHeader-companyName\\\"] span a\",\"job_description\":\"div#jobDescriptionText\",\"salary\":\"#salaryInfoAndJobType > span\"}}, ...]",  "jobSitesTimestamp": "1757296980000"}
Where the scraping config comes from
    • static.jobscan.co

    Jobscan's own asset host. Serves the JSON file that names which CSS selectors the extension reads on each job site.

Reproduce it yourself

Fetches the same endpoint the extension calls on startup and prints the per-site selector list it returns.

Requires
  • Node.js 18+ or a browser console
fetch-job-sites-config.js · js
fetch("https://static.jobscan.co/extension/job-sites.json")  .then((res) => res.json())  .then((json) => {    for (const site of json.data) {      console.log(site.label, site.url_pattern, site.dom_selectors);    }  });
How to run it
  1. 1Open a browser console or run with Node 18+.
  2. 2Paste the script.
  3. 3Compare the printed selectors against what the extension is currently shipping.

Job page details are sent to the Jobscan API when you scan or save a job.

When you use Jobscan on a job listing, the extension reads the job description, title, company name, salary, and page URL.

Save or scan actions send those job details, including the description text, to Jobscan API endpoints.

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

You click a save or scan control for a job listing.

The extension did this

The extension extracts job page details and sends the job description and related fields to Jobscan API endpoints.

Captured request
POSThttps://api.jobscan.co/v4/jobs
Fields in the request
  • Job page text
    Senior Product Manager at ExampleCo, salary $120,000-$150,000 (illustrative)

    The job description, title, company name, and salary can reveal what role and employer you are reviewing.

  • Job page URL
    https://jobs.example.com/listing/12345 (illustrative)

    The URL identifies the specific listing or job site page associated with the scan or save action.

Updated 30 September 2026apppjobnbahbomhgmcgolplkpigjlofl