Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ scripts/validate/.venv/
# Note: assets/adblock/*.txt and assets/ubo-resources.json ARE committed so the
# native ad blocker builds self-contained in CI (gen-adblock-dump.py needs them
# at `make dir` time; there is no networked list-fetch step in the release job).

# --- AI hybrid-build workflow scratch (local only, never pushed) ---
# The Strong/Weak-AI playbook, the GROK.md handoff artifact it prescribes, and
# the helper-agent directions/handoffs are working scratch — not repo content.
AI cowork.md
GROK.md
docs/agents/
8 changes: 6 additions & 2 deletions PLAN_OF_ACTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Shields panel). M4–M6 (farbling, picker, stripping) are unaffected.
- **`$csp`**: wire `engine.get_csp_directives()` → inject via `nsIHttpChannel.setResponseHeader()`.
- **domCollapser**: hide leftover placeholders (iframe/img/script) for blocked network resources.
- **Live list updates**: today lists are dump-only (`rs-blocker.patch` + `gen-adblock-dump.py`) because network sync would *delete* the bundled dump. Add a safe periodic refresh that updates without tripping the sync-delete hazard (keep dump as offline fallback).
- **Done when:** **>95% d3ward in a real GUI**, validated by the Part 2 harness — the headline goal.
- **Done when:** **>95% on adblock.turtlecute.org in a real GUI** (d3ward was archived in 2026 — turtlecute is the maintained d3ward-style replacement), validated by the Part 2 harness — the headline goal. *Progress 2026-07-08: first live run scored 116/133 (87%); the 9 missed network hosts (TikTok ads APIs, Yahoo ad-tech, Yandex Metrika) are being closed by the bundled `neonwolf-extra` supplement list.*

### M3 — Shields panel + logger (give the engine a face and an audit trail)
*The dead `neonwolf-shields.*` stub becomes a real per-site control surface.*
Expand All @@ -135,10 +135,14 @@ Shields panel). M4–M6 (farbling, picker, stripping) are unaffected.
- **Highest rebase fragility** — these touch hot, frequently-refactored Gecko code. Mark accordingly in `patches/native/MANIFEST.md`; lean on `replace_or_die`-style fail-loud anchors so a bad rebase fails CI instead of silently shipping.
- **Done when:** browserleaks shows site-varying canvas/audio/WebGL hashes; coveryourtracks reports no obvious "this is a privacy browser" tell.

> **Progress 2026-07-08 (PR #20):** M4 shipped and validated as *FPP-forward farbling* — Firefox 152's native fingerprintingProtection (per-eTLD+1 + per-session deterministic canvas/WebGL noise, verified against a plain control) rather than from-scratch Gecko noise patches; RFP is off (mutually exclusive). WebGL required also disabling LibreWolf's hidden `librewolf.webgl.prompt` silent-deny gate. Dark mode unlocked (RFP was forcing light). Shields integration done: the fingerprinting toggle drives FPP, and a per-site "Farble on this site" row writes `-AllTargets` granular overrides to **both** the FPP and baseline tiers (canvas rides `privacy.baselineFingerprintingProtection`). Known gap: audio readback is NOT farbled (FPP has no audio noise target — that was RFP-only); a native audio-farbling patch is the remaining M4 item. CoverYourTracks: "strong protection against Web tracking".

### M5 — Element picker + custom filters (complete the uBO replacement)
- **Element picker**: privileged browser chrome with an SVG highlight overlay, candidate filter generation (network URL + cosmetic selector), specificity/depth controls; write to user filter storage and rebuild the engine.
- **Custom filters page** (`chrome://neonwolf/content/shields-filters.xhtml`): editable rules, validation, rebuild-on-save.

> **Progress 2026-07-08:** element picker shipped with a uBO-style selector generator (unique-id fast path, stable-class paths, :nth-of-type disambiguation); custom-filters page shipped earlier (editor, lint, import/export); list subscriptions shipped end-to-end (lists-page manager UI + UBONetFilter fetching `neonwolf.shields.lists.subscriptions` on live refresh). M5 is functionally complete.

### M6 — Binary-level stripping (attack-surface reduction; sequenced last because it's destructive)
*Convert "hidden + policy" into actually-not-compiled. Risky for build stability — do once features are stable.*

Expand All @@ -164,7 +168,7 @@ Shields panel). M4–M6 (farbling, picker, stripping) are unaffected.
1. `make dir && make check-patchfail` — all patches (incl. `patches/native/*`) apply clean.
2. `make build` (or `make build-tests`) — compiles; run mochitests for the cosmetic/scriptlet/farbling chains in a tests-enabled build.
3. Launch the dist binary with a fresh profile (`LANG=en_US.UTF-8 MOZ_ENABLE_WAYLAND=1 … --no-remote --profile /tmp/nw-profile`) and run the automated scorecard:
- **d3ward** adblock score (M1/M2 target: >95%)
- **adblock.turtlecute.org** adblock score (M1/M2 target: >95%; d3ward is archived)
- **browserleaks** + **coveryourtracks** (M4 target: site-varying hashes, no privacy-browser tell)
- Shields per-site toggles change behavior live; logger records blocks (M3)
- Stripped components absent from `about:buildconfig` / fail to instantiate (M6)
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ page).
> It holds patches, branding, theme CSS, build config, and a Python orchestrator;
> the Firefox source tarball is downloaded and patched at build time.

## Beta downloads

A public beta for Linux and Windows is available on the
[Releases page](https://github.com/neon798/neonwolf/releases). See
[docs/BETA.md](docs/BETA.md) for install steps and known issues.

## How it's built

```mermaid
Expand Down
23 changes: 23 additions & 0 deletions assets/adblock/neonwolf-extra.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
! Title: Neonwolf Extra
! Description: Curated Neonwolf supplement closing tracker/ad-host gaps left by
! the bundled lists. Every rule uses $third-party so first-party use of the
! host (e.g. logging in to an analytics dashboard, running an ads-manager
! console) keeps working; only cross-site tracking is blocked.
! Maintainer: Neonwolf (assets/adblock/neonwolf-extra.txt — bundled-only, no
! canonical fetch URL; the live refresh serves it from the dump)
! Provenance: gaps found 2026-07-08 by probing every host on
! adblock.turtlecute.org (the maintained d3ward replacement) against the
! engine — these hosts were unmatched by all ten bundled lists.
!
! TikTok advertising / marketing-events APIs (Events API pixel on 3p sites)
||ads-api.tiktok.com^$third-party
||ads-sg.tiktok.com^$third-party
||business-api.tiktok.com^$third-party
! Yahoo ad-tech and DMP hosts
||udcm.yahoo.com^$third-party
||log.fc.yahoo.com^$third-party
||gemini.yahoo.com^$third-party
||adtech.yahooinc.com^$third-party
! Yandex analytics (bundled lists only cover paths/subdomains of these)
||metrika.yandex.ru^$third-party
||appmetrica.yandex.ru^$third-party
58 changes: 56 additions & 2 deletions assets/neonwolf.overrides.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defaultPref(
defaultPref("privacy.trackingprotection.content.protection.enabled", true);
defaultPref(
"privacy.trackingprotection.content.protection.list_names",
"easylist,easyprivacy,peterlowe,ubo-filters,ubo-badware,ubo-privacy,ubo-quickfixes,adguard-mobile,adguard-base,adguard-tracking"
"easylist,easyprivacy,peterlowe,ubo-filters,ubo-badware,ubo-privacy,ubo-quickfixes,adguard-mobile,adguard-base,adguard-tracking,neonwolf-extra"
);

// Live filter-list refresh (UBONetFilter): periodically re-fetch the lists from
Expand Down Expand Up @@ -108,13 +108,53 @@ defaultPref("browser.send_pings", false); // disable <a p
defaultPref("network.http.referer.defaultPolicy", 0); // send no referer at all
defaultPref("privacy.clearOnShutdown_v2.cookiesAndStorage", true); // actually clear cookies on shutdown
defaultPref("dom.security.mixed_content.block_active_content", true); // belt-and-suspenders with HTTPS-only
defaultPref("webgl.disabled", true); // major fingerprint vector (override in about:config if needed)
defaultPref("webgl.disabled", false); // re-enabled so FPP farbles it (+WebGLRandomization); WebGL-OFF is itself a conspicuous tell (see FPP section below)
// LibreWolf's webgl-permission.patch ALSO gates content WebGL behind a per-site
// "webgl" permission (librewolf.webgl.prompt, compiled default true) and ships
// with the doorhanger hidden (prompt.hide=true) — i.e. WebGL is SILENTLY DENIED
// everywhere, which is the exact same tell as webgl.disabled. Under the
// FPP-forward posture WebGL must actually run so +WebGLRandomization can farble
// it (empirically verified: context creation fails until this is off).
defaultPref("librewolf.webgl.prompt", false);
defaultPref("device.sensors.enabled", false); // device-motion/orientation, fingerprint surface, no desktop use
defaultPref("dom.battery.enabled", false); // battery-status API, fingerprint surface
defaultPref("dom.gamepad.enabled", false); // gamepad API, fingerprint surface
defaultPref("dom.netinfo.enabled", false); // Network Information API, fingerprint surface
defaultPref("media.peerconnection.ice.no_host", true); // prevent local-IP leak via WebRTC (still allows STUN/TURN relay)

// --- Anti-fingerprinting: FPP-forward farbling (supersedes RFP) ---
// Neonwolf presents a CONVINCING, common fingerprint via per-origin farbling,
// not RFP's uniform "hardened" spoof that stands out. Firefox's three FP modes
// (resistFingerprinting / fingerprintingProtection / baseline...) are MUTUALLY
// EXCLUSIVE and priority-ordered: RFP, when on, shadows FPP entirely. So we turn
// RFP OFF and drive FPP, which gives DETERMINISTIC per-origin canvas/WebGL noise
// (Brave-style, un-averageable) instead of RFP's per-read randomization.
//
// This also unlocks DARK MODE: RFP forces prefers-color-scheme=light
// (CSSPrefersColorScheme target). FPP's default set omits it, so websites see the
// real (dark) scheme and Firefox's native "Website appearance" setting works.
//
// FPP's default set is only 7 targets; `.overrides` (+Name/-Name) adds coverage.
// Only Canvas/EfficientCanvas/WebGL truly randomize per-origin; the rest are
// uniform spoofs. We add WebGL randomization, re-home the fork's hw-concurrency
// pin (rfp-pin-hardware-concurrency.patch -> +NavigatorHWConcurrency, verified
// -> 4), and add audio/font/timer protection. UA/screen-geometry uniform spoofs
// are deliberately NOT added (real-for-platform is more "common" than a faked
// hardened value). TIMEZONE is intentionally left REAL: verified that the JS
// timezone override is gated on the resistFingerprinting *pref* (not the
// JSDateTimeUTC target), so it can't be re-homed onto FPP by override — and a
// spoofed timezone that mismatches IP/locale is itself a tell, so coherent real
// timezone is the more "convincing" choice. This set is a starting point —
// tuned against browserleaks/coveryourtracks.
defaultPref("privacy.resistFingerprinting", false);
defaultPref("privacy.fingerprintingProtection", true);
defaultPref("privacy.fingerprintingProtection.remoteOverrides.enabled", false); // Mozilla can't relax the posture per-site
defaultPref(
"privacy.fingerprintingProtection.overrides",
"+WebGLRandomization,+WebGLRenderInfo,+NavigatorHWConcurrency,+AudioContext,+AudioSampleRate,+FontVisibilityBaseSystem,+ReduceTimerPrecision"
);
defaultPref("layout.css.prefers-color-scheme.content-override", 2); // 2 = auto/follow-theme; guard so dark mode follows the synthwave chrome

// Neonwolf: the native content-classifier ad/tracker blocker is only invoked
// via the deferred-annotation channel path; without this it never runs network
// blocking. Required for native ClassifyForCancel to execute.
Expand All @@ -139,3 +179,17 @@ defaultPref("privacy.trackingprotection.ubo.cosmetic.enabled", true);
// wins that race, so ad-blocking quality is identical. Flip to true once
// synchronous injection lands.
defaultPref("privacy.trackingprotection.ubo.scriptlet.enabled", false);

// --- Google Safe Browsing: disable the residual providers (privacy decision) ---
// The LibreWolf baseline (settings/librewolf.cfg) already disables the
// malware/phishing/blockedURIs/downloads SB features and blanks the google4 +
// legacy-google gethash/update URLs. It does NOT touch the newer google5
// provider (stock FF152 still ships it enabled) or the google4 dataSharing
// toggle, so a residual safebrowsing.googleapis.com phone-home remains until
// these are off too. Neonwolf disables Google Safe Browsing entirely — malware
// and phishing coverage instead comes from the bundled uBO lists (ubo-badware
// et al.) served by the native engine, with no Google lookup.
defaultPref("browser.safebrowsing.provider.google5.enabled", false);
defaultPref("browser.safebrowsing.provider.google5.updateURL", "");
defaultPref("browser.safebrowsing.provider.google5.gethashURL", "");
defaultPref("browser.safebrowsing.provider.google4.dataSharing.enabled", false);
48 changes: 48 additions & 0 deletions docs/BETA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Neonwolf Beta

Neonwolf is a privacy-first Firefox fork. This is a public beta for Linux and Windows. Feedback is welcome via GitHub issues.

## Download

Beta builds are on the [GitHub Releases page](https://github.com/neon798/neonwolf/releases).

- **Linux:** `Neonwolf-x86_64.AppImage` (portable) or `*.linux-x86_64.tar.xz`
- **Windows:** `*.win64.installer.exe` (installer) or `*.win64.zip` (portable)
- **macOS:** no build yet (planned for a later beta)

## Installing (the builds are unsigned)

Beta builds are **not code-signed**, so the OS will show a warning. That is expected for a beta.

### Linux (AppImage)

1. Make the AppImage executable: `chmod +x Neonwolf-x86_64.AppImage`
2. Run it.

If it will not start, install FUSE (`libfuse2` on Debian/Ubuntu).

### Linux (tar.xz)

Extract the archive and run the `neonwolf` binary inside.

### Windows

SmartScreen may show **Windows protected your PC**. Click **More info**, then **Run anyway**, and continue through the installer.

## Updates

- Neonwolf checks GitHub for a newer build about once a day and shows a banner when one is available.
- There is **no automatic update** and **no background downloader** — by design. To update, download the new build from the Releases page and reinstall (Windows) or replace the AppImage / extracted folder (Linux).

## Known issues (beta)

- Ad and tracker **network** blocking is complete, but a few cosmetic / in-page ad-script checks do not pass yet (script-injection "scriptlets" are disabled pending a fix), so third-party ad-blocker test sites score around 94%, not 100%.
- Anti-fingerprinting randomizes **canvas and WebGL** per site, but **audio** fingerprinting is not randomized yet.
- **No macOS build** in this beta.
- Builds are **unsigned** (see install steps above).
- **No built-in password manager** — by design. Neonwolf recommends Bitwarden, 1Password, Proton Pass, or KeePassXC (the first-run wizard links these).
- **Windows is less tested than Linux**; please report anything odd.

## Reporting bugs

Please open a [GitHub issue](https://github.com/neon798/neonwolf/issues) with your OS, what you did, and what happened.
Loading
Loading