You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
redirect_first_party site option (default true) — by default a redirect's destination domains (and chain hops) are registered first-party so the landed site's own resources aren't captured as third-party. Set false to keep redirect targets third-party, so filterRegex/dig apply to them under thirdParty: true — e.g. capturing the end domain of an ad/cloak redirect chain (which Chrome reaches via the ERR_TOO_MANY_REDIRECTS curl-resolve recovery). The originally-scanned domain stays first-party either way.
ERR_TOO_MANY_REDIRECTS is recovered, not hard-failed — a redirect-cloaking chain (rotating throwaway domains) can exceed Chrome's ~20-hop ceiling. The scanner now recovers via two complementary paths: (1) it first waits briefly for the browser to ride through on its own — a JS/meta hop on a committed page resets Chrome's hop counter and often carries the page to the end site for free; (2) if the page parked on chrome-error:// instead and the site has curl: true, it resolves the chain endpoint with curl (which, unlike headless Chrome, isn't served the endless-loop variant) and navigates there directly — a short hop that lands on the real end site. Either way it captures the end site's ad/tracker requests; falls back to the captured chain requests when neither path lands. The curl step is opt-in via the existing curl site option (so curl: false/unset never shells out to curl) and is also skipped under a proxy/VPN (curl runs direct and would leak the real IP / resolve from the wrong network); the free ride-through always applies.
click_elements site option — after a page loads, click a list of CSS selectors in order (searched across the main frame and any iframe) (e.g. ["a[href*='/movie/']", ".play"] to click a movie link then a play button). Reaches content via organic navigation/gesture instead of a direct deep-load, which some sites JS-redirect away, and triggers click-only content like video players. Each selector is waitForSelector-ed (visible) up to click_wait before clicking, so JS-rendered targets like video players aren't missed by racing ahead of them. The request interceptor stays attached, so the post-click page's requests run through the same filterRegex/dig matching; a click that navigates is followed and later selectors query the resulting page. Honors realistic_click (genuine trusted gesture) and cursor_mode: "ghost" (Bezier travel to the element); missing elements are skipped and never fail the scan. Settle/nav wait per click via click_wait (default 5000ms, capped at half the per-URL timeout).
--dns now also pins Chrome's page-navigation resolver via DoH. Chrome ignores --dns for navigation and reads /etc/resolv.conf directly, so a broken or filtering system resolver could ERR_NAME_NOT_RESOLVED a domain the pre-check had already resolved. When the --dns servers map to a known public DoH provider — Google, Cloudflare, Quad9, OpenDNS, AdGuard, CleanBrowsing, DNS.SB, Mullvad (incl. malware/family/unfiltered variants) — Chrome is launched with secure-DNS automatic mode pointed at that provider, so page navigation resolves through the same resolver as the pre-check. automatic (not secure) keeps a system-DNS fallback if DoH is unreachable rather than failing the batch. Applied to direct connections only — skipped when a proxy (--proxy-server) or VPN is active, since the exit/tunnel does the resolution and local DoH would be redundant or resolve geo-split domains to the wrong region. Unmapped resolvers (custom/ISP, per-account providers like NextDNS, IPv6) fall back to system DNS with a warning naming the supported providers.
--doh-disable site/CLI option (doh_disable in .nwssconfig), default off — opt out of the Chrome-navigation DoH pinning entirely. Chrome then resolves page navigation via the system resolv.conf even when --dns maps to a known provider, while the pre-check and dig still honor --dns. For networks where DoH adds latency or is blocked, or when system-path resolution is specifically wanted.
Changed
A clamped delay is now logged (--debug) — when delay exceeds its ceiling (the default 2s cap, or timeout/2 under delay_uncapped: true) it was silently reduced, so delay: 48000 quietly running as 29000ms looked like the flag was ignored. A debug line now reports the clamp and which ceiling applied (raise timeout, or set delay_uncapped: true, to lift it). The per-URL budget already reserves the full configured delay; this only surfaces the post-load dwell clamp.
DNS pre-check is paced and more tolerant under concurrency — a concurrent scan fired up to max_concurrent simultaneous c-ares UDP queries at the pinned --dns servers; the burst (rough on WSL2's UDP-through-NAT path, and rate-limited by public resolvers) produced timeouts / EREFUSED that tripped the circuit breaker (resolver errors N/M — suspending DNS pre-check) and lost the dead-host-skip optimization. The pre-check timeout is raised 2s → 4s (a clean NXDOMAIN still returns fast, so the higher ceiling only costs time when the resolver is genuinely slow), and createRotatingResolver now caps in-flight queries with a counting semaphore (default 6) so the burst is paced and excess callers queue and drain quickly. The circuit breaker itself is unchanged — these reduce the error rate so it stops tripping on healthy resolvers.
Fixed
whois availability probe is now platform-aware — the fallback used which whois (Unix-only), which on native Windows would false-negative an installed whois.exe whose whois --version errors (e.g. Sysinternals whois). Uses where on Windows, which elsewhere. No change on Linux/macOS/WSL.