Scenario
Privacy
- 31 domains
- Blocklist for this scenario
- 40 parameters
- Removed on every navigation
- disable_non_proxied_udp
- WebRTC policy
- ARMANOS Browser 153.0.7978.0
- Engine
- 3
- Free tools that send nothing
Tracking is not what one site knows about you, it is what many sites share
Open a page and it loads its own files first. Then it loads files from companies you have never heard of: an analytics script, an ad exchange, a session recorder. Each of those requests carries your address, your browser's answers about itself, and often a cookie set on a domain you never visited.
That is the whole mechanism. Two unrelated sites load the same third-party file, so one company sees both visits and joins them under a single identifier. Neither site had to cooperate with the other.
The link you clicked does the same job without a cookie. A click id in the query string travels with you and lands in the destination's own database. Then there is the device itself: screen, graphics card, fonts, clock, audio. Those answers are stable, and taken together they are rare.
The tools people usually reach for each close one road. This scenario is about closing four of them inside one profile, and about naming the roads that stay open.
| Approach | Closes | Leaves open |
|---|---|---|
| Incognito mode | Cookies, when the window closes | The same device answers, the same address, the same click ids |
| A VPN | The address a site sees | Cookies, fingerprint, WebRTC candidates, link parameters |
| A fingerprint-spoofing extension | Some values, rewritten inside the page | Rewritten properties a page can inspect; the network layer untouched |
| A second browser profile | The cookie jar | One machine underneath: same fonts, same GPU, same local address |
| A virtual machine | Almost everything, honestly | Gigabytes and a separate update cycle per identity |
| This scenario | Cookies, device, tracker requests, link parameters, WebRTC candidates | Your provider, and any site you sign into |
The scenario is a record in the code, and it is read at every launch
A scenario is not a mood. It is an object in packages/shared/src/index.js that names the start page, the injected scripts, the tracker lists to load, whether links are cleaned, and the daily action ceilings.
Privacy is also the fallback. When a profile arrives with a scenario the code does not know, profiles.js writes privacy instead of failing, and the spreadsheet importer uses it as its own default. So a profile created in a hurry lands here rather than nowhere.
One field is empty on purpose. The other scenarios carry daily ceilings on platform actions, because posting or messaging at machine speed is what gets accounts noticed. Privacy carries none, and its entry in SCENARIO_DAILY_LIMIT is zero. You are reading, not acting on a platform.
Change the scenario later and it takes effect on the next launch. The request hook remembers which scenario id it was built for and is rebuilt when that changed, so the previous scenario's rules are dropped rather than left quietly running.
- id
- privacy
- Start page
- https://duckduckgo.com
- Injected scripts
- fingerprint, stealth
- Tracker lists
- general
- Link cleaning
- on
- Daily action ceiling
- none
- Status
- shipped (feasibility: now)
Read from SCENARIOS.privacy and SCENARIO_DAILY_LIMIT in packages/shared/src/index.js.
The blocklist is thirty-one domains, and both engines read the same list
The general list holds 31 hosts: web analytics, ad exchanges, product analytics, session recorders, crash and performance reporting, mobile attribution. An entry matches the host and its subdomains. The matcher also accepts a host plus a path fragment, though every entry in the general list is a bare host.
The two engines then take different roads to the same rules. On ARMANOS Browser the list is compiled into declarativeNetRequest rules inside a small extension written per profile at launch, so blocking happens in the network stack with no hook a page can see. The built-in fallback engine has no such stack, so the app cancels the request itself in session.webRequest.
The resource types are spelled out, main_frame included. Leave them out and declarativeNetRequest matches everything except main_frame, so a click that navigates straight onto a blocked domain would pass on one engine and be stopped on the other. Two engines disagreeing is worse than either answer alone.
What a domain list cannot do is first-party analytics. When a site measures you from its own address, there is no third-party host to match. ARMANOS does have path rules for that, but only for the platforms they were tested against, and the Privacy scenario is given none. Inheriting another scenario's path rules would break unrelated pages for no gain.
| Category | Examples from the list |
|---|---|
| Web analytics | google-analytics.com, googletagmanager.com, analytics.google.com |
| Ad exchanges | doubleclick.net, googlesyndication.com |
| Social pixels | graph.facebook.com, pixel.facebook.com |
| Session recording | hotjar.com, fullstory.com, logrocket.com, mouseflow.com |
| Product analytics | mixpanel.com, amplitude.com, segment.com, heap.io |
| Crash and performance | sentry.io, crashlytics.com, bugsnag.com, newrelic.com |
| Mobile attribution | appsflyer.com, adjust.com, branch.io, kochava.com |

Forty tracking parameters come off before the request leaves
TRACKING_PARAMS is a flat list of 40 query parameter names: click ids from ad platforms, campaign tags, mail campaign ids, analytics linkers, and the professional-network set the cleaner started from. It is a named list, not a guess about what looks like tracking.
On ARMANOS Browser it becomes one declarativeNetRequest rule with a queryTransform that removes those names from main_frame and sub_frame requests. The address bar shows the clean URL and the parameter never reaches the page at all. On the built-in engine the main-frame request is redirected to the cleaned URL before it goes out.
The cleaning rule deliberately has lower priority than the blocking rules. A URL that is both a known tracker and carries a click id must be blocked, not cleaned and then let through. Getting that order wrong would turn a block into a polite pass.
Each cleaned navigation increments a counter you can read on the Protection screen. Cleaning touches only the query string: an identifier placed inside the path, or after the #, is left where it is.
Ad platform click ids
fbclid, gclid, msclkid, dclid, ttclid, twclid, yclid, wbraid, gbraid, rdt_cid, ScCid, epik, igshid, mibextid, li_fat_id
15Campaign tags
utm_source, utm_medium, utm_campaign, utm_content, utm_term
5Mail campaign ids
mc_cid, mc_eid
2Analytics linkers
_ga, _gl
2The professional-network set the cleaner started from
trk, trkInfo, lipi, lici, src, trackingId, refId, eBP, recommendedFlavor, midToken, midSig, trkEmail, connectionOf, orig, anchorTopic, contextUrn
16
WebRTC is not allowed to go around the proxy
WebRTC exists so two browsers can talk directly. To arrange that it gathers candidate addresses, including the address of your machine on your own network, and hands them to the page that asked. No permission prompt is involved and nothing appears on screen.
For a set of profiles that is the worst leak there is. The local address is identical in every profile on the computer. Ten profiles on ten different proxies, one and the same 192.168 address, and the whole group is tied together by a value no proxy can change.
ARMANOS sets the same policy on both engines. ARMANOS Browser launches with --force-webrtc-ip-handling-policy=disable_non_proxied_udp. Built-in profile windows get setWebRTCIPHandlingPolicy with the same value, and the policy is also carried in the profile's fingerprint as webrtcPolicy.
The app measures this rather than claiming it. The network diagnostics row used to be a sentence about the setting, and it would have kept printing calmly after the setting stopped applying. Now a hidden window opens with the same policy, candidates are gathered and classified: a raw private address is a failure with the address shown, a changing .local name is a pass, and a measurement that did not finish reports itself as unknown rather than as clean.
- 1
Run the leak test in your everyday browser
The tool builds an RTCPeerConnection with an empty ICE server list, so nothing goes out, and lists the addresses your browser hands over unasked.
- 2
Run it inside an ARMANOS profile
Launch a profile that has a proxy and open the same page in it.
- 3
Read the difference
A changing name ending in .local is the browser hiding the address on purpose. A raw 192.168 or 10.x address is the value that ties your profiles together.
The browser is built without the parts that phone home
ARMANOS Browser is our own Chromium build, and the build arguments strip the reporting out. enable_reporting is false, enable_rlz is false, the Google API keys are empty, and extended Safe Browsing reporting is off. Safe Browsing itself stays compiled because setting its mode to zero breaks the build; with no API keys it has no lookup server to reach.
In the page, the stealth script replaces navigator.sendBeacon. Beacons fire while a page is unloading, which is exactly when a tracker ships what it collected, and an ordinary request filter no longer sees them in time. The replacement returns true, so pages behave normally, and it adds one local counter.
The profile start page is served by a loopback HTTP server inside the app, so a launch is never announced to anyone. The single outbound request it makes is the IP lookup, and that goes through the profile's own proxy, because the point of the page is showing you the exit address a site would see.
Cookies and site logins stay in the profile directory on your computer. Only profile settings reach your account. When a session moves between your own machines it travels through a folder you choose, as a file encrypted with scrypt and AES-256-GCM.
- enable_reporting
- false
- enable_rlz
- false
- use_official_google_api_keys
- false
- google_api_key
- empty
- enable_extended_safe_browsing_reporting
- false
- safe_browsing_mode
- 1, with no keys to reach a server
The gn arguments the shipped engine is built with, from engine/scripts/build-mac.sh. The Linux build reuses the same list.
Check the result yourself, and we never see the numbers
Three free tools live on this site, and all three compute inside your browser. That is not a promise about our servers, it is the shape of the code: there is no fetch, no XHR, no beacon and no socket in any of them, and a stand fails the build if one appears.
The fingerprint check reads twelve values, including the ones that decide the matter and that many checkers skip: the pixels a WebGL readback returns, the audio rendering, the font list. It condenses them into an eight-character code you can compare by eye.
The leak test asks the browser for its own candidate addresses with an empty ICE server list. Pointing it at somebody's STUN server would tell that server about you, which is the opposite of the job it exists to do.
The third tool counts distinct machines. Profiles are separate browsers with no shared memory, so a page in one knows nothing about another, and we cannot count for you even if we wanted to. You paste the codes, it counts the repeats.
- 1
Measure your everyday browser
Open the fingerprint check and copy the eight-character code.
- 2
Measure each profile
Open the same page inside each ARMANOS profile and copy each code.
- 3
Count the repeats
Paste all the codes into the counter on that page. Two profiles with one code look like one machine to a site.
- 4
Go deeper inside the app
The profile fingerprint window runs a self-test of 25 readings against the browser that profile actually launches with, and scores it out of 100.
What this does not do
- It does not make you anonymous. Your provider still sees that you connected, and any site you sign into knows exactly who you are.
- The blocklist for this scenario is 31 domains. It is a curated list of well-known trackers, not a full ad-blocking ruleset, and a site's own first-party analytics is not on it.
- Link cleaning removes 40 named query parameters. An identifier placed in the path, or after the #, survives.
- Without a proxy the profile goes out from your own address. Isolation and a consistent device are not an IP change.
- On the built-in fallback engine an extension's own blocking rules are executed by ARMANOS, not by the engine. Rules it cannot express are counted and skipped, and that number is printed rather than hidden.
- We do not claim that sites cannot tell. What is shipped here is isolation, a consistent device, and less data leaving on its own.
How to check
Every claim above has a file behind it and, where it can be measured, a stand that fails the moment it stops being true.
- The scenario record says what this page says
- packages/shared/src/index.js (SCENARIOS.privacy, SCENARIO_DAILY_LIMIT) · apps/desktop/src/lib/profiles.js (create)
- Tracker blocking and link cleaning really run on the shipped engine, measured through our own loopback proxy
- apps/desktop/src/lib/tracker-rules.js · apps/desktop/test/блокировка-живьём.js
- This scenario inherits no path rules written for other platforms, and both engines compile the same rules with their hosts
- apps/desktop/src/lib/forkExtension.js · apps/desktop/test/слежка-по-хостам.js
- An enabled blocker never promises more than the engine delivers, and unparsed rules are counted
- apps/desktop/src/lib/dnrBlock.js · apps/desktop/test/builtin-blocking.js · apps/desktop/test/extension-limits-honest.js
- The WebRTC verdict is measured, not asserted
- apps/desktop/src/main/main.js (probeWebrtc, classifyWebrtcCandidates) · apps/desktop/test/leak-verdict.js
- The free tools make no network call at all
- apps/web/components/tools/LeakCheck.tsx · apps/web/test/тест-утечки.js · apps/web/test/инструмент-отпечатка.js
Read next
Browser fingerprint check
Twelve readings and one eight-character code, computed in your browser.
WebRTC leak test
Which addresses your browser hands out without being asked.
ARMANOS Browser
The Chromium build that substitutes the fingerprint inside the engine.
Proxies
A proxy per profile, and the geo the fingerprint is aligned to.
Promise register
Every claim on this site with the file and the stand behind it.
Two profiles on the free plan
Install ARMANOS, create a profile on the Privacy scenario, then run the fingerprint check in it and in your everyday browser and compare the two codes.