Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
67cef8e
Build world-class privacy and governance foundation
mdheller Jun 18, 2026
d6498d4
Add source build packaging and fix macOS build tooling
mdheller Jun 18, 2026
51599f7
Add BearBlocker — native adblock-rust content classifier and cosmetic…
mdheller Jun 18, 2026
af6bd07
Add BearBlocker build wiring to bearbrowser-patches.py
mdheller Jun 18, 2026
2b6a7bb
Add nightly DMG build workflow for developer use
mdheller Jun 18, 2026
ed9b87b
Add hold-queue status bar app and wire agent-runtime profile
mdheller Jun 18, 2026
2ec3ba0
Close governance loop: auto-launch, receipt bridge, LaunchAgent
mdheller Jun 18, 2026
fed531b
Seal extension ecosystem, add registry and unseal mechanism, add Linu…
mdheller Jun 18, 2026
81ffe50
Native SponsorBlock + keyboard nav + Fedora CI; seal extension surface
mdheller Jun 18, 2026
642cbbd
Fix crash on macOS 26 when opening Gmail or any SSO/OAuth popup
mdheller Jun 18, 2026
0129f8e
Remove gesture-timing popup gate — eliminates fingerprinting vector
mdheller Jun 18, 2026
cce1971
Expand fingerprinting shield: 10 new vectors closed
mdheller Jun 18, 2026
d553548
Close final fingerprinting gaps: WebGPU, font enum, rAF timing, devic…
mdheller Jun 18, 2026
558e80b
Engine-level font enumeration and timer precision hardening
mdheller Jun 18, 2026
f8df5df
Add BearCapture, BearClip, BearVault actors; update BearSponsor and r…
mdheller Jun 18, 2026
d28bcf5
Defeat JS shield detection + close locale, resource timing, identity …
mdheller Jun 18, 2026
34e7d3d
Normalize Accept-Language header, complete navigator identity, networ…
mdheller Jun 18, 2026
4de625f
Achieve 36/36 fingerprint regression — fix four shield crashes and si…
mdheller Jun 18, 2026
4f50c3d
Close remaining fingerprinting gaps — 47/47 regression coverage
mdheller Jun 18, 2026
400d846
Extend fingerprint shield to 59/59 — WebGL params, Range BCR, perf en…
mdheller Jun 18, 2026
32239b3
Advance fingerprint shield to 72/72 — AudioBuffer, plugins PDF set, S…
mdheller Jun 18, 2026
0e2b105
Advance fingerprint shield to 86/86 — Math precision JSC→V8 override
mdheller Jun 18, 2026
231c5c3
Advance fingerprint shield to 91/91 — timeOrigin, Intl.supportedValue…
mdheller Jun 18, 2026
3825d16
Advance fingerprint shield to 92/92 — canvas noise, pdfViewerEnabled
mdheller Jun 18, 2026
7068fc9
Advance fingerprint shield to 96/96 — WebKit-only API removal, perfor…
mdheller Jun 18, 2026
4d37ac9
Advance fingerprint shield to 108/108 — Chromium API presence stubs
mdheller Jun 18, 2026
0548c3c
Advance fingerprint shield to 111/111 — window.chrome stub with prope…
mdheller Jun 18, 2026
48a547d
Fix navigator.vendor: 'Apple Computer, Inc.' → 'Google Inc.'
mdheller Jun 18, 2026
ca23712
Restore Safari-consistent identity — revert Chrome impersonation dive…
mdheller Jun 18, 2026
6173aa2
Advance fingerprint shield to 101/101 — Math native concealment, _nat…
mdheller Jun 18, 2026
71b256f
Plug _nat registration gaps — getShaderPrecisionFormat, FontFaceSet.c…
mdheller Jun 18, 2026
9dc6dfe
Plug remaining _nat registration gaps — WebGL2 getShaderPrecisionForm…
mdheller Jun 18, 2026
77167d2
Force WKWebView Aqua appearance — CSS system color consistency
mdheller Jun 18, 2026
f98e47a
RFP audit: remove WebKit-shield contamination and dead/contradictory …
mdheller Jun 18, 2026
1b8160f
Add Gecko RFP regression harness; fix cross-profile drift it caught
mdheller Jun 18, 2026
f3bfad6
Wire Gecko RFP harness into package.json verify targets
mdheller Jun 18, 2026
5cebbdf
Harden QUIC/TLS cross-connection supercookies: disable 0-RTT early data
mdheller Jun 18, 2026
71f03e4
Switch DoH provider Cloudflare -> Quad9; harden DNS/HTTPS-RR/ECH layer
mdheller Jun 18, 2026
6676641
Harness: validate policies.json strips to valid strict JSON
mdheller Jun 18, 2026
5ea0cad
Harmonize network/TLS privacy cohort across both profiles
mdheller Jun 18, 2026
25e7156
Agent policy: block enterprise-root import + EME; harness locks anti-…
mdheller Jun 18, 2026
9731da3
T0: empirical fingerprint measurement harness + first real baseline
mdheller Jun 18, 2026
4d4ea0a
Measurement: add WebRTC IP-leak vector (confirmed clean both profiles)
mdheller Jun 18, 2026
726db8c
T3 spec: font + text-metric uniformity; track text-metric readback leak
mdheller Jun 18, 2026
b8f73d9
T3 implementation plan (no-holes runbook) + track both metric paths
mdheller Jun 18, 2026
d114f63
T3 runbook: add Section 0 — build-environment on-ramp (turnkey)
mdheller Jun 18, 2026
05a23f4
T3 plan: correct architecture to nsRFPService helper + DOM call sites
mdheller Jun 18, 2026
431a7ca
T3 W4 (canvas): real Gecko patch for text-metric quantization — appli…
mdheller Jun 18, 2026
4636ff9
CI: anti-fingerprint workflow — yes, this runs in GitHub Actions
mdheller Jun 18, 2026
e30b75a
Fix CI: timezone cohort assertion + patch-apply path bug
mdheller Jun 18, 2026
cb7f926
T3 W4: close OffscreenCanvas hole in the text-metric patch
mdheller Jun 18, 2026
d24d16d
W1+W2: bundle metric-compatible fonts + font.system.whitelist allowlist
mdheller Jun 18, 2026
e611f5c
W6: audio farble patch — closes the one vector Brave beats us on
mdheller Jun 18, 2026
9d7a000
Tier-3: real-binary measurement via geckodriver + fix timezone false-…
mdheller Jun 18, 2026
b6cdc1b
Wire anti-fp patches into the build (mirror-safe) + verify full sequence
mdheller Jun 18, 2026
60f9f56
Trigger the real compile: build anti-fp branch on nightly-linux + mea…
mdheller Jun 19, 2026
cabd3c8
Fix nightly-linux startup failure (broken block scalar) — unblocks th…
mdheller Jun 19, 2026
cd8f31c
Fix Linux build: convert BSD `sed -i ''` to Python in bearbrowser-pat…
mdheller Jun 19, 2026
3a20107
Build: skip missing pref-pane assets gracefully (unblocks past patch-…
mdheller Jun 19, 2026
feefdc8
Build: strip stale --with-l10n-base from mozconfig (3rd infra fix)
mdheller Jun 19, 2026
c813419
Tor mode Phase 1: SOCKS routing + cohort alignment profile + design doc
mdheller Jun 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
129 changes: 129 additions & 0 deletions .github/workflows/anti-fingerprint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Anti-fingerprint

# Three tiers of verification for the anti-fingerprint track:
# 1. harness-and-measure — config harness + empirical fingerprint baseline
# (real Gecko via Playwright). Fast; the regression gate.
# 2. patch-apply — proves the gecko-patches/ apply to the pinned Firefox
# source (the `check-patchfail` equivalent). No compile.
# 3. full-build — manual: real `make build` + geckodriver measurement of
# the actual binary. Heavy; needs a large/self-hosted
# runner (a full Firefox build OOMs/overflows the stock
# 14 GB GitHub runner — the project's Forgejo/Woodpecker
# pipeline is the natural home; this is the GH scaffold).

on:
pull_request:
push:
branches: [main]
schedule:
- cron: '23 7 * * 1'
workflow_dispatch:

env:
# Keep in sync with the build repo's `version` file.
FIREFOX_VERSION: '150.0.1'

jobs:
# ── Tier 1: config posture + measured fingerprint baseline ─────────────────
harness-and-measure:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install deps + Gecko engine
run: |
npm ci || npm install
npx playwright install --with-deps firefox
- name: Config harness (static + runtime RFP) — HARD GATE
run: node scripts/verify-gecko-rfp.mjs
- name: Fingerprint measurement (both profiles)
run: |
node scripts/measure-fingerprint.mjs --profile human-secure --json > fp-human-secure.json
node scripts/measure-fingerprint.mjs --profile agent-runtime --json > fp-agent-runtime.json
echo "human-secure: $(jq -r '.neutralized' fp-human-secure.json)/$(jq -r '.total' fp-human-secure.json) neutralized"
echo "agent-runtime: $(jq -r '.neutralized' fp-agent-runtime.json)/$(jq -r '.total' fp-agent-runtime.json) neutralized"
- name: Upload fingerprint scorecards
uses: actions/upload-artifact@v4
with:
name: fingerprint-scorecards
path: fp-*.json

# ── Tier 2: do the gecko-patches still apply to pinned Firefox source? ──────
patch-apply:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch pinned Firefox source
run: |
url="https://archive.mozilla.org/pub/firefox/releases/${FIREFOX_VERSION}/source/firefox-${FIREFOX_VERSION}.source.tar.xz"
echo "fetching $url"
wget -q "$url" -O firefox-src.tar.xz
tar xf firefox-src.tar.xz
- name: Dry-run apply every anti-fp patch (fail on reject)
run: |
patches="$(pwd)/gecko-patches"
cd "firefox-${FIREFOX_VERSION}"
fail=0
while IFS= read -r p; do
echo "==> $p"
if ! patch -p1 --dry-run -i "$p"; then
echo "::error file=$p::patch does not apply to firefox-${FIREFOX_VERSION}"
fail=1
fi
done < <(find "$patches" -name '*.patch' | sort)
exit $fail

# ── Tier 3: real build + measure the actual binary (manual, large runner) ──
full-build:
if: github.event_name == 'workflow_dispatch'
# A full Firefox build needs ~40 GB disk + lots of RAM/time. Override with a
# large or self-hosted runner: set repo variable BUILD_RUNNER (e.g. a
# self-hosted label) — falls back to ubuntu-latest, which will likely run out
# of space (kept here so the wiring is visible; the Forgejo pipeline is the
# production path).
runs-on: ${{ vars.BUILD_RUNNER || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
path: overlay
- name: Checkout build repo
uses: actions/checkout@v4
with:
# Set repo variable BUILD_REPO to the LibreWolf-style build repo
# (the one with Makefile + scripts/bearbrowser-patches.py + assets/patches.txt).
repository: ${{ vars.BUILD_REPO }}
path: build-repo
- name: Register anti-fp patches into the build
run: |
cp overlay/gecko-patches/anti-fingerprint/*.patch build-repo/patches/
for p in overlay/gecko-patches/anti-fingerprint/*.patch; do
echo "patches/$(basename "$p")" >> build-repo/assets/patches.txt
done
- name: Validate patches apply (fast gate before the slow build)
run: cd build-repo && make check-patchfail
- name: Build BearBrowser
run: cd build-repo && make bootstrap && make build
- name: Set up measurement deps
run: cd overlay && npm ci || (cd overlay && npm install)
- name: Measure the REAL binary (geckodriver — authoritative)
run: |
# Locate the built binary (Linux: dist/bin/{firefox,bearbrowser};
# macOS: dist/*.app/Contents/MacOS/*). measure-fingerprint.mjs --bin
# drives it via geckodriver — Playwright (Juggler) can't drive a stock
# build. This is the authoritative measurement: it sees what Playwright
# masks (e.g. RFP timezone, real letterboxing).
bin="$(find build-repo -type f \( -name firefox -o -name bearbrowser \) -path '*dist*' 2>/dev/null | grep -vE '\.dSYM' | head -1)"
if [ -z "$bin" ]; then echo "::error::built binary not found under build-repo dist"; exit 1; fi
echo "measuring: $bin"
export PATH="$PWD/overlay/node_modules/.bin:$PATH"
node overlay/scripts/measure-fingerprint.mjs --profile human-secure --bin "$bin" --json > fp-real-human-secure.json
node overlay/scripts/measure-fingerprint.mjs --profile agent-runtime --bin "$bin" --json > fp-real-agent-runtime.json
echo "human-secure (real binary): $(jq -r '.neutralized' fp-real-human-secure.json)/$(jq -r '.total' fp-real-human-secure.json)"
jq -r '.rows[] | select(.status=="LEAKING") | " LEAK: \(.vector)"' fp-real-human-secure.json
- name: Upload real-binary scorecards
uses: actions/upload-artifact@v4
with:
name: real-binary-scorecards
path: fp-real-*.json
8 changes: 7 additions & 1 deletion .github/workflows/feature-plane.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ on:
- "scripts/verify-interactive-sidecar.sh"
- "scripts/verify-comparison-plane.sh"
- "scripts/verify-agent-sidecar-contract.py"
- "scripts/bearbrowser-create-receipt.py"
- "scripts/bearbrowser-update-receipt.py"
- ".github/workflows/feature-plane.yml"
push:
branches: [main]
Expand Down Expand Up @@ -53,6 +55,8 @@ on:
- "scripts/verify-interactive-sidecar.sh"
- "scripts/verify-comparison-plane.sh"
- "scripts/verify-agent-sidecar-contract.py"
- "scripts/bearbrowser-create-receipt.py"
- "scripts/bearbrowser-update-receipt.py"
- ".github/workflows/feature-plane.yml"
workflow_dispatch:

Expand Down Expand Up @@ -84,7 +88,9 @@ jobs:
scripts/bearbrowser-governance-queue.py \
scripts/bearbrowser-sidecar-server.py \
scripts/bearbrowser-sidecar-status.py \
scripts/verify-agent-sidecar-contract.py
scripts/verify-agent-sidecar-contract.py \
scripts/bearbrowser-create-receipt.py \
scripts/bearbrowser-update-receipt.py

- name: Shell syntax
run: |
Expand Down
124 changes: 124 additions & 0 deletions .github/workflows/nightly-dmg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: BearBrowser Nightly DMG

on:
schedule:
- cron: '0 4 * * *'
workflow_dispatch:
push:
branches: [main]
paths:
- 'settings/**'
- 'scripts/bearbrowser-patches.py'
- 'branding/**'

jobs:
nightly-dmg:
name: Build and package (macOS)
runs-on: macos-15
timeout-minutes: 360

env:
MOZBUILD_STATE_PATH: ${{ github.workspace }}/.mozbuild
VERSION: 150.0.1
RELEASE: 1
PROFILE: human-secure

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Cache Mozilla toolchain
uses: actions/cache@v4
with:
path: .mozbuild
key: mozbuild-${{ env.VERSION }}-macos15-v1
restore-keys: mozbuild-${{ env.VERSION }}-macos15-

- name: Cache Firefox source tarball
uses: actions/cache@v4
with:
path: build/workspaces/${{ env.PROFILE }}-${{ env.VERSION }}-${{ env.RELEASE }}/source/firefox-${{ env.VERSION }}.source.tar.xz
key: ff-tarball-${{ env.VERSION }}

- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: cargo-${{ env.VERSION }}-macos15-v1

- name: Set up workspace from LibreWolf mirror
run: |
bash scripts/apply-sourceos-overlays.sh \
--profile ${{ env.PROFILE }} \
--ref latest \
--workspace-root build/workspaces

- name: Fetch Firefox source tarball
working-directory: build/workspaces/${{ env.PROFILE }}-${{ env.VERSION }}-${{ env.RELEASE }}/source
run: make fetch

- name: Apply BearBrowser patches
working-directory: build/workspaces/${{ env.PROFILE }}-${{ env.VERSION }}-${{ env.RELEASE }}/source
run: make dir

- name: Bootstrap Gecko build environment
working-directory: build/workspaces/${{ env.PROFILE }}-${{ env.VERSION }}-${{ env.RELEASE }}/source/bearbrowser-${{ env.VERSION }}-${{ env.RELEASE }}
run: |
MOZBUILD_STATE_PATH=${{ github.workspace }}/.mozbuild \
./mach --no-interactive bootstrap --application-choice=browser

- name: Build BearBrowser
working-directory: build/workspaces/${{ env.PROFILE }}-${{ env.VERSION }}-${{ env.RELEASE }}/source/bearbrowser-${{ env.VERSION }}-${{ env.RELEASE }}
run: MOZBUILD_STATE_PATH=${{ github.workspace }}/.mozbuild ./mach build

- name: Package BearBrowser.app
run: |
bash scripts/bearbrowser-package-source-build.sh \
--workspace build/workspaces/${{ env.PROFILE }}-${{ env.VERSION }}-${{ env.RELEASE }}/source/bearbrowser-${{ env.VERSION }}-${{ env.RELEASE }} \
--profile ${{ env.PROFILE }} \
--out-dir build/nightly \
--version ${{ env.VERSION }} \
--skip-verify

- name: Create DMG
id: dmg
run: |
DATE=$(date +%Y%m%d)
DMG="BearBrowser-${{ env.VERSION }}-${DATE}-dev.dmg"
hdiutil create \
-volname "BearBrowser" \
-srcfolder "build/nightly/BearBrowser.app" \
-ov -format UDZO \
"build/nightly/${DMG}"
echo "name=${DMG}" >> $GITHUB_OUTPUT
echo "path=build/nightly/${DMG}" >> $GITHUB_OUTPUT

- name: Upload DMG artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.dmg.outputs.name }}
path: ${{ steps.dmg.outputs.path }}
retention-days: 30

- name: Publish nightly release
if: github.ref == 'refs/heads/main'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DATE=$(date +%Y-%m-%d)
TAG="nightly-${DATE}"
# Replace any same-day release rather than fail on duplicate tag
gh release delete "$TAG" --yes 2>/dev/null || true
gh release create "$TAG" \
"${{ steps.dmg.outputs.path }}" \
--title "BearBrowser Nightly ${DATE}" \
--notes "Automated nightly build from \`main\`.

**Not notarized — developer use only.**
To open: right-click BearBrowser.app → Open (bypasses Gatekeeper).

Commit: \`${{ github.sha }}\`
Firefox base: ${{ env.VERSION }}" \
--prerelease
Loading
Loading