Skip to content

feat(security): implement Brave Shields-equivalent ad and tracker blo…#117

Open
Antra1705 wants to merge 1 commit into
PandyaJeet:mainfrom
Antra1705:feat/brave-shields-ad-blocker
Open

feat(security): implement Brave Shields-equivalent ad and tracker blo…#117
Antra1705 wants to merge 1 commit into
PandyaJeet:mainfrom
Antra1705:feat/brave-shields-ad-blocker

Conversation

@Antra1705

Copy link
Copy Markdown
Contributor

Summary

Root Cause

SuperBrowser markets itself as "Zero ads" but the promise only applied to search-result link filtering (ad_filter.py). No network-level blocking existed for the in-app <webview> browser — every ad request, tracker pixel, and analytics script loaded exactly as it would in vanilla Chromium.

Changes Made

frontend/electron/blocker.cjs (New)

  • Initializes ElectronBlocker from EasyList + EasyPrivacy on both session.defaultSession and session.fromPartition('persist:superbrowser') — dual-session coverage so neither the main window nor the webview is unprotected
  • Independent trackersBlocker instance (EasyPrivacy only) classifies blocked requests as ads vs. trackers
  • 7-day TTL check — re-downloads and re-caches filter lists weekly via filterListsUpdatedAt in settings.json
  • Offline fallback: parses bundled easylist.txt/easyprivacy.txt snapshots from frontend/electron/filters/ if network fetch fails
  • Per-domain whitelist enforcement via blockingWhitelist in settings.json using existing settings.get/settings.set IPC bridge
  • IPC handlers: blocking:get-stats, blocking:get-settings, blocking:set-domain-enabled, blocking:toggle

frontend/electron/main.cjs

  • await initBlocker() called inside app.whenReady() after registerIpcHandlers() and before createMainWindow()
  • Python backend startup wait increased to 30s to eliminate ECONNREFUSED race condition on slower machines

frontend/electron/preload.cjs

  • Exposes blocking namespace on superBrowserDesktop bridge: getStats, getSettings, setDomainEnabled, toggle, onStatsUpdate
  • Exposes webviewPreloadPath for dynamic preload injection into the webview

frontend/electron/webview-preload.cjs (New)

  • Requires @cliqz/adblocker-electron-preload to inject cosmetic CSS hide rules into guest pages

frontend/src/App.jsx

  • Added partition="persist:superbrowser" and preload={window.superBrowserDesktop.webviewPreloadPath} to <webview>
  • Renders <ShieldsPanel> in the BrowserPanel toolbar

frontend/src/components/ShieldsPanel.jsx (New)

  • Shield icon with animated red badge counter (total blocked requests)
  • Green when blocking active, grey when domain is whitelisted
  • Popover: master domain toggle, ads/trackers breakdown, independent switches, "Reload to apply" affordance

frontend/package.json

  • Added @cliqz/adblocker-electron and @cliqz/adblocker-electron-preload
  • Added bundled filter snapshots to build.files

Testing

Blocker engine verification (verify_blocker.cjs):

--- Adblocker Verification Script ---
Loading filter files...
Parsing combined blocker (EasyList + EasyPrivacy)...
Parsed combined blocker successfully!
Parsing trackers-only blocker (EasyPrivacy)...
Parsed trackers-only blocker successfully!

Running test cases...

URL: https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-1234

  • Expected: shouldBlock=true, isTracker=false
  • Result: blocked=true, isTracker=false
    ✅ Test passed!

URL: https://www.google-analytics.com/analytics.js

  • Expected: shouldBlock=true, isTracker=true
  • Result: blocked=true, isTracker=true
    ✅ Test passed!

URL: https://example.com/assets/main.js

  • Expected: shouldBlock=false, isTracker=false
  • Result: blocked=false, isTracker=false
    ✅ Test passed!

Testing serialization and deserialization...
✅ Serialization/deserialization verification passed!

🎉 ALL TESTS PASSED SUCCESSFULLY! Blocker engine is 100% correct.

Build & packaging:

  • npm run build — ✅ 1530 modules, built in 1.06s, zero errors
  • npm run pack — ✅ native deps compiled including @cliqz/adblocker-electron, packaged for darwin/arm64
  • node --check on all .cjs files — ✅ zero syntax errors
  • ESLint on ShieldsPanel.jsx — ✅ zero errors

Application startup logs:

[electron:wait] [SuperBrowser adblocker] Fetching fresh filter lists...
[electron:wait] [SuperBrowser adblocker] Filter lists downloaded and cached successfully.
[electron:wait] [backend] INFO: Started server process [61911]
[electron:wait] [backend] INFO: Application startup complete.
[electron:wait] [backend] INFO: Uvicorn running on http://127.0.0.1:8000

Impact

  • Fulfills the "Zero ads" promise for the in-app browser, not just search results
  • Blocking is ON by default with no user action required
  • Per-domain whitelist allows users to disable shields on sites that break with blocking active
  • Filter lists are cached locally and updated weekly — no repeated network fetches on every launch
  • ad_filter.py search-link filtering is completely unchanged — no regression to existing search modes (SuperSEO, SuperAI, SuperReview)
  • No automated CI build/test workflows exist in this repo — PR labeling and star check only

Closes #81

Screenshots

1st 2nd 3rd 4th

…cking

Signed-off-by: Antra1705 <antra.1705@gmail.com>
@github-actions github-actions Bot added the gssoc:approved GSSoC approved PR - earns base 50 pts label Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved GSSoC approved PR - earns base 50 pts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Implement default ad and tracker blocking (Brave Shields equivalent)

1 participant