Legal
Privacy Policy
Effective date: August 9, 2026 · Applies to: Scam Blocker & Ad Blocker — Adless (browser extension for Google Chrome and Microsoft Edge), v0.9.14 and later.
What changed on 9 August 2026. Nothing new is collected. This update widens what this page tells you about collection that was already happening, because earlier wording understated it: the Shield scam report is gated by a flag that is now switched on rather than off for everyone; starting a free trial posts a one-way hash to our server, so the trial is no longer described as entirely local; there are six kinds of outbound connection rather than five; a fourth value (a random trial id) reaches Chrome's synced storage; and the seven Shield checks each report under their own name — one of which, brand-clone, reports without showing you a warning. Every one of those is set out in full below.
Adless's single purpose, as declared on the Chrome Web Store: Adless blocks and neutralizes unwanted and harmful web content — ads, trackers, anti-adblock walls and phishing/scam pages — and tidies the page layout that remains. Everything below describes the data handling that purpose requires, and nothing else.
Which browsers this policy covers. Adless is a Chromium extension published on the Chrome Web Store (for Google Chrome) and the Microsoft Edge Add-ons store (for Microsoft Edge); the extension code is identical on both. Where this policy names a browser mechanism by its Chrome name, the Microsoft Edge equivalent applies when you run Adless on Edge: browser sync roams the payment library's licence record to your Microsoft account instead of your Google account, and the built-in safe-browsing layer that Adless does not replace is Microsoft Defender SmartScreen instead of Google Safe Browsing. Nothing else about the data handling differs between the two browsers.
Adless is built on a simple principle: an ad blocker exists to reduce the amount of your life that gets tracked, so it must never become a tracker itself.
The short version
- We collect nothing by default. No browsing history, no visited URLs, no page contents, no identifiers. Adless has no analytics: nothing about you or the sites you visit is sent on a schedule, and nothing about a page is sent at all unless you tap Send on a report or switch on the opt-in Shield scam report. Requests do happen on a schedule — updated blocking data is downloaded, and a subscriber's licence is re-checked with our payment provider about once a day — and they are listed one by one under Network connections. To be precise about the word "collect": Adless's content scripts do read the page on your device, because hiding a cookie banner, recognizing a detector, or spotting a phishing form requires seeing the page. The Security Shield's reading goes further than layout — it inspects what you type into fields (including password, one-time-code and card-number fields), form structure, visible page text, and what you copy to the clipboard. All of it is judged in memory and dropped: none of it is stored, and none of it is transmitted. See The Security Shield for exactly what is read and what survives.
- Your settings stay on your device. Settings, allowlists, and the protection counter live in your browser's local extension storage only. The "Adless has protected you N times" number is computed and stored entirely in your browser and is never transmitted anywhere, ever. One thing is not local, and we name it rather than let "everything stays on your device" cover it: the payment library that runs subscriptions keeps its licence record in
chrome.storage.sync, which Chrome replicates to your Google account. It is an install date, a licence key and your subscription status — a payment record, not browsing data. See What syncs to your Google account. - Nothing about your browsing leaves your device unless you tap Send or switch it on. There are exactly three such messages, and all three are listed in full under Network connections:
- the breakage report — you tap Send; it carries that one site's host (
example.com), never the full address; - the false-positive report — you tap twice, and the second tap follows a screen showing you the exact bytes. This one does carry the full web address of the page that was blocked, because a wrong block cannot be investigated without the address that was blocked. We say so plainly here rather than round it down: it is the only thing Adless ever sends that contains a full URL, you are shown it before it goes, and nothing is sent if you do not tap;
- the Shield scam report — a setting that is off by default and that, once you turn it on, sends two fields whenever a Shield scam check fires: which check fired, and the bare domain it fired on (for example
evil-site.com). It has its own section: The Shield scam report.
None of the three carries page content, anything you typed or copied, or any user, device, install, session or licence identifier. There is no fourth.
- the breakage report — you tap Send; it carries that one site's host (
- We never sell or monetize your data. Only three outside parties receive anything, and none of it is browsing data. (1) Web3Forms, an email service, delivers a breakage report you tapped Send on — it carries only that site's host, and it is entirely your choice; see The opt-ins you control. (2) ExtensionPay, our subscription provider, receives the per-install licence key when the extension checks whether Pro is still active. (3) Stripe handles the checkout itself, in its own hosted page, and is where any card detail is entered — never in the extension. Nothing is ever sold, and nothing goes to an advertiser or a data broker. The Shield scam report reaches no third party at all: it goes to our own server and stops there.
What is stored locally (and the one row that is not)
Everything in this list lives in chrome.storage.local on your device, is never transmitted, and is deleted when you uninstall the extension — except the two items marked as exceptions below: the subscription/licence record, and the anonymous trial id. Both of those are kept in chrome.storage.sync, which Chrome replicates to your Google account, and each is set out in full below.
- Your settings (protection level, category toggles, YouTube layout preferences) — making the extension do what you asked.
- Your allowlist (paused/excluded sites, permanent and 24-hour temporary) — honoring your per-site choices. The allowlist itself never leaves extension storage; the only thing a web page can see is a single boolean (
ct-paused-v1in that page's own localStorage) saying whether that one site is paused, so the anti-adblock camouflage can switch off instantly there. No page can learn which other sites you paused (v0.7.2 deliberately removed an older full-list mirror for exactly this reason). - Protection counters (per-tab and lifetime totals) — the stats shown in the popup, "Adless has protected you N times". The number is a tally of four things Adless observed itself doing on the pages you opened: ad/tracker requests that failed to load and whose host is on our bundled blocklists, known-malicious hosts among them, cookie banners hidden, and anti-adblock probes neutralized. Only counts are kept — a set of running integers. No host, URL, page, or timestamp behind any count is ever recorded, and the totals are never transmitted. They exist only in your browser's local storage and are deleted with the extension.
- Trial state — the second exception to this list. The cached tier, expiry and last-check time live in
chrome.storage.localand are never transmitted. Starting a trial is not local: when — and only when — you tap Start free trial, a salted one-way SHA-256 hash of an anonymous random trial id is posted once tocdn.adless.pro/v1/trial, so the 7-day trial cannot be reset over and over by clearing storage. The id is a random UUID generated on your device — no URL, domain, page content or email. It is set out as item 6 under Network connections the extension makes, and the id itself is covered in What syncs to your Google account. - Subscription/licence record — the exception to this list. Three keys written by the payment library (ExtensionPay): an install timestamp, an opaque per-install API key, and the cached subscription record. They exist so the extension knows whether Pro is active. These live in
chrome.storage.sync, notchrome.storage.local, so Chrome replicates them to your Google account and to your other signed-in devices, and a copy can persist in that account after you uninstall. Payment/entitlement data only — no URL, domain, page content or browsing history. Set out in full in the next section. - Security Shield state: salted SHA-256 hashes of domains where you previously typed a password, a timestamp of the last warning shown, and your yes/no answer to the Shield report prompt. This lets the credential sentry tell a login page you use often from a brand-new one, without ever storing which sites those are — the list holds hashes and a last-used time, never plaintext domains. Nothing you typed is stored here, or anywhere: no password, one-time code, card number, recovery phrase or clipboard text, in any form. None of this is transmitted. See The Security Shield.
The blocking itself is performed by Chrome's built-in declarativeNetRequest engine using rule lists bundled with the extension. Your web requests are never routed through, read by, or logged by our code or our servers.
What syncs to your Google account: the payment library's licence record
Adless has no cross-device sync feature. Your settings, allowlist, YouTube layout and protection counters are not synced — they are local to each install, and a second computer starts fresh.
There are two exceptions, and for the first it is Chrome, not Adless, that does the copying. Adless takes payments through ExtensionPay (the extpay library), and that library stores its records in chrome.storage.sync rather than chrome.storage.local. Chrome treats the sync area as account data: it replicates whatever is there to your Google account and to every device where you are signed into Chrome with extension sync switched on. The library exposes no setting to keep it local, so this is not something you can turn off inside Adless. Rather than let a general "everything stays on your device" sentence paper over that, here is the whole of it — three keys written by the payment library:
extensionpay_installed_at— one timestamp: the moment the payment library first ran in this Chrome profile (e.g.2026-07-31T00:21:04.512Z), used to compute trial length. Nothing else. It is written on every install, free or paid, once, on first run, with no action from you — the payment library is what decides whether you are on the free tier, so it runs even if you never look at Pro. This is the one key that reaches Chrome Sync for someone who never clicks Upgrade.extensionpay_api_key— an opaque per-install API key minted by ExtensionPay. It identifies and authenticates this licence to ExtensionPay. You never choose it, it is not a password, and it unlocks nothing except this extension's own Pro flag. Only installs that have opened the checkout or the "Restore purchase" page have one. A free user who never taps Upgrade has no key, and in that case the extension makes no request to the payment provider at all.extensionpay_user— the subscription record ExtensionPay returns, stored as received: whether you have paid, when you paid, whether the subscription is active, past due or cancelled, any cancellation date — and the email address you gave at checkout. Adless's own code never reads that email, never displays it and never sends it anywhere; the library stores the response verbatim. Only populated for installs that have been through checkout or "Restore purchase" — never for a free user.
One more synced value, and this one is ours: an anonymous trial id. This is the second exception. To stop the 7-day free trial being reset over and over by clearing storage, Adless generates one random UUID the first time you tap Start free trial and stores it as ct:trial:anon-id in chrome.storage.sync, so Chrome replicates it to your account and it survives a reinstall. It is created only if you start a trial — an install that never does has no such key. It is a random number and nothing more: not derived from you, your device, your email or anything you browse, and it identifies no person. A salted one-way hash of it — never the id itself — is what is posted once to cdn.adless.pro/v1/trial (item 6 of Network connections).
What this is: payment and entitlement plumbing. What it is not: browsing data. None of these four keys contains a URL, a domain, a page title, a search, a click, a keystroke or anything you typed into a page. Those four are the whole of what Adless puts in the sync area: three written by the bundled payment library, and the one random trial id above.
Two consequences that follow from Chrome's behaviour rather than from anything Adless does, stated because they are the parts people are most likely to be surprised by:
- Pro can appear on another device on its own. If you buy on one computer and sign into Chrome on another, the licence key travels with your Google account, so Pro can light up there without you restoring it by hand.
- Uninstalling does not necessarily clear it. Local extension storage is deleted with the extension; the synced copy lives in your Google account and can outlive the install, and can reappear if you install Adless again under the same account. Chrome's own account and sync controls are where that data is managed.
The licence key is also the one thing the extension transmits on a schedule: see item 2 of Network connections below.
The opt-ins you control
Adless sends nothing about a page on a schedule, and nothing about a page at all without either an explicit tap from you or a setting you switched on yourself. (The requests that do run automatically are the data downloads and the subscription check in Network connections; neither carries anything about a page.) There are three such paths in the whole extension: two you tap — the breakage report described immediately below, and the false-positive report described under "Network connections" — and one you switch on, the Shield scam report, which is off until you turn it on and has its own section below.
Breakage reports (you tap Send)
The popup's "Something's broken on this site?" report happens only when you initiate it. If a page misbehaves, you can tap Send report; nothing is sent until you do, and nothing is remembered or queued if you don't.
What a breakage report contains: the host of the site you were on (e.g. example.com — never the full URL, path, query string, or fragment), the names of the rule categories you had active (such as "ads" or "camouflage"), and a coarse major.minor extension version (e.g. 0.7). That is the whole payload. What it never contains: full URLs, page contents, search terms, watch history, cookies, IP-derived location profiles, or any user or device identifier. The only timestamp is the server's receive time. This host-only signal is what powers our 24-hour fix promise: it tells us which site broke without telling us anything about you.
Where the report goes, honestly and in full. The report is posted to our own server (cdn.adless.pro/v1/breakage), which stores it so we can triage it. A stored row nobody reads fixes nothing, so the server then forwards the same four fields — host, active categories, coarse version, receive time — as a plain email to the maintainer's inbox, and it uses a third-party email service, Web3Forms (api.web3forms.com, a US company), to deliver that email. The email's subject line is Adless breakage: <host>. Web3Forms therefore processes the host you reported, on our behalf, for the sole purpose of delivering that message. It receives nothing else: no identifier, no URL, no account, no address of yours — a breakage report contains no personal data to begin with. At most one email per host per hour is sent, and duplicate reports are collapsed into a count. This data is not sold, not used for advertising, and not combined with anything else. If you never tap "Send report", nothing about you or the sites you visit reaches our server or Web3Forms at all.
A note on automatic telemetry. An earlier design contemplated automatic "selector-health" pings that would report when a YouTube layout fix stopped matching a page. That is not active in the current version — it is reserved for a possible future release, and if it ever ships it will be opt-in and off by default, with no URLs or browsing data. What does ship is a different, narrower reporting path that is not a button you tap: the Shield scam report. It is off by default, it only ever runs if you switch it on, and it sends exactly two fields — which scam check fired, and the bare domain it fired on. It is described in full in The Shield scam report below.
Network connections the extension makes
Adless makes outbound connections to six kinds of endpoints. Two run automatically and carry no browsing data — the first uploads nothing at all, and the second carries only a subscriber's own licence key; two fire only when you tap a Send button, and each shows you what it will send first; the fifth is a setting that is off by default and sends nothing at all unless you switch it on; the sixth fires once, only if you start a free trial:
- Config CDN (
cdn.adless.pro) — the extension polls three separate static files on analarmsschedule, not one:config.json— the remote config: updated YouTube selector maps, threat-block rules and feature flags.threats/prefixes.bin?v=N— the threat database itself, the local list the phishing/malware check is compared against.threats/manifest.json— the threat-coverage manifest, which tells the options page how many entries the shipped database holds and how fresh it is.
All three are plain HTTPS GETs with standard cache headers (an If-None-Match ETag). Each one carries no cookies, no identifiers, and no information about your browsing — nothing is uploaded, and the server learns only that some copy of Adless asked for a file. Payloads are schema-validated data only — never code.
- Payment provider (installs that have opened checkout or restored a purchase) — subscription status is read from ExtensionPay, and checkout itself is hosted by Stripe. Two things are worth stating plainly. First, what is sent: a GET to
extensionpay.comcarrying the opaque per-install API key described in What syncs to your Google account, and nothing else — no URL, no page, no browsing data, no identifier we created. It runs on the 24-hour revalidation alarm and after checkout, so this is the one automatic, scheduled request that carries anything specific to your install. A free user who has never opened checkout has no key, and for them the extension makes no request to the payment provider at all. Second, what comes back and where it goes: the subscription record, which the payment library caches inchrome.storage.syncand Chrome therefore copies to your Google account. Payment details are entered on and handled entirely by Stripe in an ordinary browser tab; Adless never sees your card number, and no card, bank or billing-address detail is ever handled by the extension. - Breakage-report endpoint (only when you tap "Send report") — the host-only report described above, posted by the extension to our own server at
cdn.adless.pro/v1/breakage. Nothing is sent unless you initiate it, and the payload is limited to that one site's host, your active rule categories, and a coarse extension version. Our server is not the last stop: it relays those same fields onward as an email to the maintainer via the third-party service Web3Forms (api.web3forms.com). The extension itself never contacts Web3Forms — the relay happens server-side — but you should know the host you reported passes through a third party's mail pipeline on its way to a human. - False-positive report (only when you tap "Send this report") — if Adless warns you about a page and it is wrong, the warning page offers "Report a false positive". Tapping it shows you the exact payload first; nothing is sent until you tap again. The payload is the full web address of the page that was blocked (
pageUrl— the complete URL, including its path and query string), the address in our list that matched it, the threat class, which feed listed it, the date it was listed, and a coarsemajor.minorextension version. This is the only message Adless ever sends that contains a full URL, and it exists because a wrong block cannot be investigated without the address that was wrongly blocked. The design compensates by making you the one who decides: the exact bytes are rendered on screen before the second tap, and what you see is literally what is posted — the function that builds the preview is the function that builds the request body, so a field cannot be added to the payload without appearing in the preview. It is posted tocdn.adless.pro/v1/false-positiveand nowhere else. If you never tap, the report is not stored, not queued, and not retried. - Shield scam report (off by default — only if you switch it on) — when one of the Security Shield's on-device scam checks fires on a page, Adless can tell our own server two things: which check fired and the bare registrable domain it fired on (e.g.
evil-site.com). Nothing else. This is the one connection in this list that is neither a plain data download nor a button you tapped, so it is described field by field in The Shield scam report below: what it sends, what it can never send, what our server does with it, how to switch it off, and its current server-side flag state. It is posted tocdn.adless.pro/v1/telemetryand nowhere else, and it is never relayed to any third party. - Trial anchor (only if you start a free trial) — when you tap Start free trial, and only then, Adless posts a salted one-way SHA-256 hash of an anonymous random trial id to
cdn.adless.pro/v1/trial. This exists so the 7-day trial cannot be reset over and over by clearing storage. The id is a random UUID generated on your device: the request carries no URL, no domain, no page content, no email and no name, it fires once on that tap and never on a schedule, and it goes only to us — never to a third party. If you never start a trial, this request never happens.
The Shield scam report (opt-in, off by default)
This is the one thing Adless can send that is not a button you tapped, so it is set out here in full.
What it is for. The Security Shield runs seven scam checks entirely on your device: Credential Sentry (a password being typed into a lookalike sign-in page), scare pages ("your PC is infected"), seed-phrase fishing, fake checkouts, paste-and-run ("press Win+R and paste this"), clipboard swapping, and brand-clone (a page presenting itself AS a brand while asking for a password or a card, on a domain that brand does not own). They report under seven names — one name per check, so a report always says which check actually fired. (Until August 2026 paste-and-run and clipboard swapping shared a single name: they are one detector family behind one switch, and while these reports were switched off for everybody the distinction bought nothing. Now that the reports can be switched on, telling the two apart is the entire reason to send them, so paste-and-run has its own name.) The public feeds that list scam sites are always behind reality — a domain registered this morning is invisible to every feed until somebody reports it, which is exactly the gap our own store listing warns you about. The Shield scam report closes that gap: it lets the browsers whose Shield fired first warn everybody else. Being honest about the trade: the report does not make your own browsing safer. For six of the seven checks, the one that fired already warned you, on your device, before anything was sent. The seventh, brand-clone, is still being validated: it reports what it found without showing you a warning — which is why we name it here rather than leave it unsaid. What the report does is make the next person's browsing safer.
It is off by default. Nothing is sent until you say yes.
- You are asked once, on the Shield warning card itself, the first time a meaningful Shield warning appears: "Help protect others?"
- Answering no is final. You are never asked again.
- You can turn it on or off at any time in Settings → Protection → "Help protect others". Switching it off takes effect immediately and nothing further is sent — there is no queue, no retry, and no "last batch".
- If the stored consent value is ever missing or unreadable, it is treated as not granted. Corruption can only ever turn this feature off, never on.
What it sends — the entire payload, both fields, nothing else:
signalId— which check fired, as a fixed keyword from a closed list of seven. It is one ofcredential-sentry,scare-page,seed-phrase,fake-checkout,clipboard-swap,brand-clone,paste-run. Seven detectors, seven keywords — one each. A value outside that list sends nothing at all rather than something approximate.registrableDomain— the bare registrable domain (eTLD+1) of the page. Subdomains are stripped:login.secure.evil-site.co.ukis reduced toevil-site.co.uk, and nothing else survives. Example:evil-site.com.
There is no third field. The report does not contain the full URL, the path, the query string, the fragment, the subdomain, the page title, any page content, anything you typed or copied, a user id, a device id, an install id, a session id, a licence or subscription identifier, a timestamp of yours, or any counter. Pages that are not ordinary web pages (chrome://, extension pages, file://), bare IP addresses, and anything the reducer cannot resolve to a registrable domain produce no report at all rather than a partial one.
This is enforced in code, not by promise: the function that builds the report constructs the entire request body itself and can only ever return those two fields or nothing, and "nothing" means no request is made. Our server refuses a body that carries any other key rather than quietly accepting and stripping it.
Where it goes. To our own server at https://cdn.adless.pro/v1/telemetry and nowhere else. It is never relayed, sold, shared, or passed to any third party, and it is not used for advertising or combined with anything else.
What our server does with it. Reports are counted per domain over a rolling 7-day window. When 5 reports name the same domain inside that window, the domain enters a review queue marked pending. Promotion is never automatic. A pending row is an invitation for a human to look; a person decides whether a domain really is a scam site before it can reach the threat lists Adless ships. Raw report rows are deleted once they age out of the counting window (the 7 days plus one day of slack); what can outlive them is a queue entry holding a domain, a count and two dates. No report is ever attributed to a person, an installation, or a browser.
About your IP address. As with every request any browser makes to any server, our server sees the network address the report arrived from. It is not stored: it is immediately turned into a salted hash that lives in memory only, used solely to stop one sender flooding the endpoint. It is never written to the database, never attached to a report, and never logged beside a domain. The extension sends no cookies and no credentials with the request.
Current status: enabled, as announced. Beyond your own consent, this feature is also gated by a server-side flag (shield.telemetry). That flag is published as true as of remote config v99 (2026-08-07).
What changed for you: nothing, unless you had already said yes. The report is still off by default, still requires your explicit consent, and is still revocable at any time in Settings. It still carries exactly two fields — the id of the check that fired and the registrable domain — and still never carries a URL, a page, anything you typed, or any identifier for you. The flag was a second lock on top of your consent; releasing it means people who had already opted in, and were until then sending nothing, now send those two fields.
Why. The on-device check that spots a brand-new impersonation page cannot be improved without knowing how often it is right, and we deliberately collect no usage data to infer that from. Those two fields are the minimum that answers it. Anyone who would rather not take part leaves the switch off; the protection does not depend on it.
A correction we owe you. It was briefly true between config v88 and v93 (2026-08-05 to 06) while a new on-device check was validated in shadow mode, and was returned to false because the published privacy page had not yet been updated to say so. This policy promises that such a change is announced before it takes effect; on that occasion the flag moved first and this page was updated afterwards, which is not what we promised. No report was sent by anyone who had not already opted in — the consent gate never moved — but the sequencing was wrong, and we would rather record it than quietly restate the status. That is why the v99 enable was done the other way round: this page carried the announcement and was verified live at adless.pro/privacy BEFORE the flag moved. The same order binds every future change to it, exactly as Changes to this policy requires.
How the threat check works (and why the check itself sends nothing)
Adless's phishing and malware protection runs entirely on your device. The list of malicious addresses is downloaded as a static file, the same way the rule lists are, and the comparison happens inside your browser against a local copy. No address, hostname, hash, or hash prefix you visit is transmitted at lookup time, on any schedule, or as a side effect of any other request — including DNS lookups, which we do not perform. The check itself is a one-way street: looking a page up costs no network request of any kind.
The only three ways anything about a page you visited can leave your device are the breakage report (a bare host, one tap) and the false-positive report (the full address of a page we blocked, shown to you before it is sent, two taps) — both of which require you to tap Send — and the Shield scam report, which requires you to have switched it on and which carries only a check name and a bare domain. There is no fourth.
This is enforced mechanically, not by policy: tools/verify-no-egress.mjs fails CI if any bundle contains a network call whose arguments can reach a page URL or hostname, and it fails CI outright if the content scripts — where the address check runs — contain a network call at all. The three reports above are the only sanctioned exceptions to that rule; each is listed by name in the checker, each has a dedicated test pinning what it may send, and the Shield scam report's test fails CI if its consent gate loosens or if its payload ever grows a third key.
Adless's address check is a second opinion that costs no lookup: no address you visit is transmitted in order to check it. That is a statement about the address check specifically, not a claim that the extension never sends anything — the three reports above are exactly what it can send, and they are listed so this sentence cannot be read as more than it says. Chrome's own Safe Browsing catches things we do not and should stay switched on.
What we never do
- No collection of browsing history, visited URLs, or page contents. There are exactly three exceptions, and each one is a decision you make: the breakage report, which carries one site's bare host and is sent only when you tap Send; the false-positive report, which contains the single full address you were warned about and is sent only after you have been shown the exact payload and tapped Send a second time; and, if you switch it on, the Shield scam report, which carries only which detector fired and the bare registrable domain of the page — never the URL, the path, or the page itself. None of the three is a history: each is a single page you chose to tell us about, or a single domain a scam check fired on.
- No collection of what you type, or of what you copy. The Shield inspects typed field values (including password, one-time-code and card fields) and clipboard writes on your device, in memory, to decide whether to warn you — and discards every one of them. None of it is stored and none of it is transmitted, in any form; the content scripts that read it contain no network code at all, which is checked in CI on every push.
- No PII gathered from you or your browsing: no names, no IP logging, no fingerprinting, no ad IDs, and no email address collected by the extension. The one personal detail that exists anywhere in Adless is the email address a subscriber gave our payment processor at checkout: it comes back as part of the subscription record and is cached by the payment library, so it sits in
chrome.storage.syncalongside the rest of that record. Adless's own code never reads it, never shows it, and never sends it anywhere. It is not taken from your browser, your pages, or any account you did not deliberately use to pay. - No selling, renting, or monetizing of data — never, under any circumstance, and there is nothing of that kind to sell. Exactly three outside parties ever receive anything, all of them service providers doing a job we asked them to do: the email service Web3Forms delivers a breakage report you tapped Send on (the host only, no personal data); ExtensionPay receives the per-install licence key when the extension checks whether Pro is active; and Stripe runs the checkout page where a subscriber enters their payment details. No browsing data reaches any of them, and nothing reaches an advertiser, a broker, or anybody else.
- No automatic transmission of the popup's protection counts — those numbers never leave your browser.
- No remote code execution — remote payloads are data, validated by schema.
- No tracking pixels, analytics SDKs, or third-party trackers in the extension.
Anti-adblock camouflage and cookie-banner hiding
Adless ships four content scripts, and exactly one of them runs on every site (see the store listing's permission justifications): the YouTube layout script on YouTube only, camouflage.js on a curated list of 13 named publisher domains and nowhere else, feedGuard.js on two Facebook hosts, and bannerHide.js on all sites. bannerHide.js is the all-sites one and the only reason Chrome shows "read and change all your data". It hides cookie banners and also runs the Security Shield's scam detectors — the section below describes what those read, and it is more than layout. Every one of the four reads page structure on your device — that is what finding a banner, or recognizing a detector, requires — and every one operates entirely inside the page and transmits nothing. What survives the banner-hiding and camouflage reading is counts only: no URLs, no page contents, no identifiers.
One detail worth stating plainly, because it is how the popup's counter works: the cookie-banner script also listens for resources on the page that failed to load, and when a failed resource's host appears on our own bundled ad/tracker or malware lists it adds 1 to a local counter. It reads that address only to decide whether the block was ours, in memory, in the moment; the address is discarded immediately and never stored or sent. What survives is a number. Requests to sites not on our lists are ignored entirely, and an ordinary broken image on an ordinary site is never counted.
The camouflage script installs its hooks only on a short curated list of sites with known anti-adblock walls — on every other site it installs nothing: no hooks, no globals, no interceptors — and it additionally refuses to run on sensitive surfaces (login, SSO, payment, and banking pages). That carve-out belongs to the camouflage script alone; it is not a rule about the Shield, which is described in the next section and which deliberately does run on login and payment pages. Where the camouflage script does run, it reads the page's own state locally (hostname, the ct-paused-v1 pause boolean, the page's Trusted Types policy, and the class/id of elements a detector measures) so it can recognize a detection probe. None of that is stored or sent; the only thing it passes on is a count of probes neutralized.
The Security Shield: what it reads, and what happens to it
Adless ships a Security Shield: six on-device detectors that warn you when a page looks like a credential-harvesting login, a fake "confirm your recovery phrase" form, a scare page ("your computer is infected"), a fake checkout, a paste-and-run ("press Win+R and paste this") lure, or a clipboard swap that replaces a crypto address you copied. They ride along in the same all-sites content script that hides cookie banners, so they are available on any page — which is the point, because a phishing page can be any page and a brand-new scam domain is on no blocklist yet.
We are going to be specific about what that costs in reading, because a detector that watches for credential harvesting has to look at the things credential harvesting targets, and describing it as "layout inspection" would be false.
Two facts up front, because both cut against the assumption the previous section might leave you with:
The Shield does run on login, SSO, payment and banking pages, on purpose. The camouflage script's carve-out for those pages does not apply here. A credential-harvesting detector that excused itself from login pages would be excusing itself from the only pages it exists for — a fake bank sign-in is a login page, and that is precisely when we need to be looking.
The Shield does not read your email. On the major webmail hosts — Gmail, Outlook, Yahoo, AOL, Proton, Zoho (including its regional sites), GMX, mail.com, Fastmail and Yandex — the fourth bullet below, form structure and visible page text, does not happen at all. Not read and discarded: not read. The four detectors that depend on it (scare page, fake checkout, brand clone, paste-and-run) return an empty result without touching the page, so the message body, the subject lines in your headings and any phone number in a signature are never looked at. Our tests assert that the read never occurs, rather than that the result came back blank, because those are different promises and this is the stronger one.
Two limits on that sentence, because it should mean exactly what it says:
- It is a list of named hosts, not a pattern. Webmail you host yourself — a Roundcube or Zimbra install on your own company or university domain — is not on the list, and its page text is read like any other site's. We match whole provider hostnames only. Matching a leading label like
webmail.instead would let anyone switch these four detectors off on a page they control just by naming their host that way, and a detector an attacker can disable is worth less than the courtesy it would buy. - The tab title is still read, everywhere. The credential-checking detector described below reads
document.titleon every site, webmail included, to tell a real sign-in page from a page impersonating one. It stays local like everything else here and is never transmitted.
The rest of this section still applies on those sites, and deliberately so: the field-level detectors, the clipboard comparison and the address checks all keep working, so a recovery-phrase form or a swapped crypto address inside a webmail page is still caught. What we give up is scanning the text of your mail — which costs almost nothing, because phishing pages are not hosted on your mail provider. The link in the message leads somewhere else, and that somewhere else is where the full Shield is waiting.
What the Shield reads on the page you are on:
- The value of the field you are typing in, on every keystroke and after every paste. This includes
type="password"fields, one-time-code / 2FA fields, and raw card-number fields. It is read to answer questions like "is this a wallet recovery phrase being typed into a page that is not your wallet?" - The values of neighbouring one-word fields, in one specific case: when the field you are editing holds exactly one word, the seed-phrase detector joins the one-word values of its sibling inputs. This exists because fake "confirm your recovery phrase" pages deliberately spread the 12 or 24 words across 12 or 24 separate boxes, so that no single field ever contains the phrase.
- What kind of field it is — its
type,autocompletetoken,name,id,placeholder,aria-labelandmaxlength— to distinguish a password from a one-time code from a card number from ordinary text. - Form structure and visible page text — whether card-number, expiry and CVC fields are present; the page title,
h1/h2headings, imagealttext,aria-labels and logo filenames (which brand a fake checkout is imitating); a capped window of visible body text; the position, stacking order and viewport coverage of top-level elements (the full-screen scare overlay); and how far the page has inflated your back-button history. - What you copy. When you press copy or cut, the Shield reads the text that actually reached your clipboard and the text you had selected, and compares them. That comparison is the detector: it catches a page that silently substitutes an attacker's crypto address for the one you highlighted, and a page that hides a shell command inside what looks like an ordinary copy.
What happens to all of it: nothing. Each value is held in a local variable long enough for a detector to answer one yes/no question, and is then dropped when the function returns. The only thing that survives is the verdict — show a warning, or stay silent. No typed value, no clipboard text, no page text, no form field, no page URL and no page title is written to extension storage, written to a log, or transmitted anywhere. Password, one-time-code and card values in particular are never stored and never sent, in any form, hashed or otherwise.
This is machine-enforced, not merely promised. A CI gate, tools/verify-no-egress.mjs, scans every built content-script bundle and fails the build if it contains a network sink of any kind — fetch, XMLHttpRequest, sendBeacon, WebSocket, image beacons, and so on. The code that performs all of the reading above therefore has nothing to transmit with. It is not that we choose not to send this data; the scripts that see it are structurally incapable of sending it, and the build fails if that ever stops being true.
The one thing the Shield keeps. To tell a new login page from one you use all the time, the credential sentry records a salted SHA-256 hash of the registrable domains where you have previously typed a password — a length-capped, least-recently-used list of hash plus last-used timestamp in local extension storage. It never stores plaintext domains, never stores anything you typed, and only the password path writes to it (entering a one-time code or a card number never does). It stays on your device, is never transmitted, and is deleted when you uninstall the extension.
Where the Shield does not run. Not on a site you have paused, and not in embedded frames — the top frame only.
The one time something leaves your device, and only if you say yes. If — and only if — you have switched on the Shield scam report, a detector that actually fires causes the extension's background service worker to send two fields: which check fired, and the bare registrable domain of the page (for example evil-site.com). That setting is off by default and is described in full in The Shield scam report.
The point to carry over from this section is what that report does not contain: none of the field values, clipboard text, form structure or page text described above is part of it, in any form, hashed or otherwise. The only page-derived thing that ever goes on the wire is the domain.
Precisely how that works, since it is the kind of detail worth stating rather than glossing: the reading and the sending are done by two different pieces of the extension. The content script does the reading and has no network code at all. When a detector fires it passes the page's address to the background worker over Chrome's internal extension messaging — that message stays inside your browser and never touches the network — and the background worker reduces that address to the bare registrable domain before any request is made. The full URL, with its path and query, is discarded at that point and is never transmitted. And if the setting is off, which is the default, the background worker sends nothing at all.
FeedGuard on Facebook: what it reads, and what happens to it
Adless ships one more content script that reads page data, and it deserves naming rather than folding into "content scripts read pages". FeedGuard (feedGuard.js) is a Pro feature that runs on exactly two hosts — www.facebook.com and web.facebook.com, top frame only — and nowhere else. Chrome does not load it on any other site. It is off until you turn it on.
What it does. Facebook delivers sponsored posts inside the feed payload rather than as separate requests, so Chrome's blocking engine cannot see them. FeedGuard reads a copy of Facebook's own feed responses on your device, classifies which units are ads, and hides the sponsored ones from your feed.
What it reads. The feed response body Facebook's own page already requested — post text, sponsorship markers, and the structural fields that distinguish a sponsored unit from an ordinary post.
What happens to it. It is classified in memory and dropped. No feed content, post text, author, URL, host or id is stored, logged, or transmitted. The only thing that survives is a local integer — the "ads spotted" figure in the popup, which is deliberately kept separate from the protection total and is never sent anywhere. Like every other content script, feedGuard.js contains no network sink at all, which tools/verify-no-egress.mjs fails CI over if it ever stops being true.
What it does not do. It never alters the network payload: the feed response Facebook's client receives is byte-identical to what the server sent — FeedGuard reads a copy and never touches the original, so nothing is injected into or rewritten in the response, and no post is reordered. Hiding a sponsored post is done locally in your own browser, by marking it hidden in the page after the fact; it is reversible and changes nothing Facebook sees. FeedGuard closes itself on login and ad-manager pages, adds no permission, and does not change the install prompt.
Permissions
If Chrome told you Adless can "read and change all your data on all websites", this is the section that explains it. That prompt is real and we are not going to bury it. It is caused by the one content script Chrome requires us to register on every site, plus the matching host permission — not by the API permissions listed further down.
Site access — the reason for the prompt
- One
<all_urls>content script (bannerHide.js): it hides cookie banners, counts what was blocked, and runs the Security Shield's seven on-device scam detectors — which is the substantial reason the match is all-sites, since a phishing page can be any page. What those detectors read is set out in full under The Security Shield above, and it is more than layout. All of that reading happens locally, in the moment, and is then discarded. What is kept is a set of counts: no URLs, no page contents, no identifiers, and nothing that leaves your browser. - Host permission
*://*/*(all http/https sites), for three dependencies: the all-sites content script above; the Shield Link-Cleaner (Pro, off by default, user-toggled), a single declarativeNetRequest redirect rule that strips tracking parameters such asutm_source,fbclidandgclidas a top-level page loads — Chrome only lets that rule fire on URLs the extension holds a host permission for, and decorated links come from anywhere; and the popup reading the current tab's address so it can show and change per-site state and reset the "on this page" counter between videos. It is deliberately*://*/*and not<all_urls>: nofile://, noftp://. Because that host permission already covers reading the current tab, Adless does not also requestactiveTab. - Anti-adblock camouflage, on 13 named sites: the script that hides Adless from anti-adblock detectors used to be registered on every site too. Since v0.7.3 it is registered only on the publishers we have actually seen run those detectors, and Chrome does not load it anywhere else. That list can only change in a new, reviewed version of the extension; no server can add to it.
- FeedGuard, on two Facebook hosts:
www.facebook.comandweb.facebook.comonly, described above. - The YouTube layout script: registered on
*://*.youtube.com/*and loaded by Chrome nowhere else.
Chrome shows a single blunt sentence for all of that. The long version is the list above — every script, what it reads, and what it keeps — and our promise is that we will never widen this in an update without telling you plainly, in advance, exactly what changed and why.
API permissions
- declarativeNetRequest: Chrome — not Adless — matches our rule lists against requests and blocks ads, trackers and known malicious sites. Adless never sees the requests or the addresses you load.
- storage: to save your preferences, allowlist and counters. Both storage areas are used, and the second one matters: local for everything above, and
chrome.storage.syncfor the payment library's threeextensionpay_*keys, which Chrome replicates to your Google account — see What syncs to your Google account. - alarms: to schedule temporary-allowlist expiry, the three CDN downloads, and the 24-hour licence revalidation.
Adless does not request tabs, webNavigation, webRequest, activeTab, or history, bookmark or cookie access.
This website (separate from the extension)
Everything above is about the extension. This site is a different thing, and we hold it to the same standard of saying so:
- Analytics: we run Umami, a cookie-free, privacy-focused analytics tool, to count page views on this site. It sets no cookies and builds no cross-site profile. It does not run in the extension and knows nothing about your browsing anywhere else.
- Contact form: the form on our Help page is delivered by Web3Forms, which receives the email address and message you type and forwards them to our inbox.
- Google Fonts: this site loads its typefaces from Google's font CDN, so Google receives the request (and therefore your IP address) when a page here loads.
- YouTube: our home page shows a video thumbnail served from YouTube's image CDN, which is likewise a request to Google.
None of the four has any connection to the extension, and none of them can see anything you do in your browser outside this website.
Children
Adless does not knowingly collect any data from anyone, including children.
Changes to this policy
Material changes will be announced in the extension's changelog and on the store listing before they take effect. We will never retroactively broaden what is collected.
Contact
Questions or concerns? Email support@adless.pro — the support address listed on the Chrome Web Store listing for Adless.