Is Story Saver safe?
Story Saver is high risk. Each startup, Story Saver sends ex.zework.com a per-install ID. First run creates a 25-char random string plus language, sent via '?id='; later starts resend it via '?on='. Captured: GET ex.zework.com/?on=TWzOFYmRCW8Iv2dI4m46PDQDMen-GB.…
Who publishes itad - 1 other listing from the same operator, 1 of them carrying a finding
ad - 1 other listing from the same operator, 1 of them carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
1 other listing published from this account. 1 of them carries a finding.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Persistent tracking beacon sent to ex.zework.com on every startup
Each startup, Story Saver sends ex.zework.com a per-install ID.
First run creates a 25-char random string plus language, sent via '?id='; later starts resend it via '?on='.
Captured: GET ex.zework.com/?on=TWzOFYmRCW8Iv2dI4m46PDQDMen-GB.
You start your browser with Story Saver installed.
The extension sends a GET request to ex.zework.com with a persistent identifier tied to your installation.
No user interaction, no download, no story viewed. The request fires on every startup automatically.
| Field | Value | Why it matters | |
|---|---|---|---|
Your installation ID | TWzOFYmRCW8Iv2dI4m46PDQDM | A 25-character random string generated on first run and stored permanently, letting the server recognize your install across sessions. | |
Browser language | en-GB | Your configured browser locale, appended to the ID during first-run generation. Reveals a language/region signal. |
The stored tracking value: 25 random characters plus the browser language code at first install. Written once, sent on every later startup.
chrome.storage.local key 'KEYUSER'TWzOFYmRCW8Iv2dI4m46PDQDMen-GB
The beacon code in background.js:
// Runs at top-level service worker scope — fires on every SW startup.
chrome.storage.local.get('KEYUSER', function(result) {
var iduser = result.KEYUSER;
if (iduser) {
// Returning install: report existing ID
fetch("https://ex.zework.com/?on=" + iduser);
} else {
// First run: generate a 25-char random ID + browser language, store, then report
var keyidmake = randomkey(25) + navigator.language;
chrome.storage.local.set({ "KEYUSER": keyidmake });
fetch("https://ex.zework.com/?id=" + keyidmake);
}
});- ex.zework.com
Receives the per-install tracking ID on every service-worker startup. Domain is listed in host_permissions (*.zework.com). Ownership isn't publicly disclosed in the CWS listing.
Browser fingerprint with language code transmitted to ex.zework.com
Story Saver builds a tracking ID at install from a random string plus browser language, sent to ex.zework.com via ?id=.
Later startups resend it via ?on=.
Captured: ?id=hxAQRRPlggQxWu2pJiWDpsqK9en-GB, ?on=TWzOFYmRCW8Iv2dI4m46PDQDMen-GB.
You install Story Saver for the first time.
The extension generates a persistent identifier that includes your browser's language setting and transmits it to ex.zework.com.
The identifier is stored in chrome.storage.local and re-sent on every subsequent startup, allowing the server to track your install across sessions.
| Field | Value | Why it matters | |
|---|---|---|---|
Random component | hxAQRRPlggQxWu2pJiWDpsqK9 | A 25-character string generated once at install using Math.random(). Provides uniqueness across users. | |
Browser language | en-GB | Your navigator.language value appended to the random string. Encodes language and regional locale in the tracking key. |
Identifier generation and transmission (background.js:11995-12015):
// Runs at top-level service worker scope on every startup.
chrome.storage.local.get('KEYUSER', function(result) {
var iduser = result.KEYUSER;
if (iduser) {
// Returning user: resend stored identifier
fetch("https://ex.zework.com/?on=" + iduser);
} else {
// First run: generate composite ID and register with server
var keyidmake = randomkey(25) + navigator.language; // e.g. "hxAQRRPlggQxWu2pJiWDpsqK9en-GB"
chrome.storage.local.set({ "KEYUSER": keyidmake });
fetch("https://ex.zework.com/?id=" + keyidmake);
}
});
// randomkey() helper (background.js:19-28):
function randomkey(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
while (result.length < length) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}- ex.zework.com
Receives the composite ID on first run (?id=) and every startup after (?on=). Declared in manifest as *.zework.com. Ownership not disclosed in the CWS listing.
What it can do
Permissions this extension asks for, as declared in version 2.9.30. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to. The current listed version is 3.0.8, which we have not unpacked yet.
Read and change your data on instagram.com
*://*.instagram.com/*
Read and change your data on facebook.com
*://*.facebook.com/*
Read and change your data on whatsapp.com
*://*.whatsapp.com/*
Read and change your data on fbcdn.net
*://*.fbcdn.net/*
Read and change your data on zework.com
*://*.zework.com/*
React to what is on a page without reading the page
declarativeContent
Start, monitor and manage your downloads
downloads
Run its own code inside the pages you visit
scripting
Store data in your browser
storage
See the address and title of every tab you have open
tabs