Skip to content

Instantly share code, notes, and snippets.

@maxmilton
Last active June 12, 2025 23:44
Show Gist options
  • Save maxmilton/8f352d731a40e6deacda043ec84b8be3 to your computer and use it in GitHub Desktop.
Save maxmilton/8f352d731a40e6deacda043ec84b8be3 to your computer and use it in GitHub Desktop.
Open URL "brave://adblock" and paste into custom filters.
! https://gist.github.com/maxmilton/8f352d731a40e6deacda043ec84b8be3
! https://github.com/gorhill/uBlock/wiki/Static-filter-syntax
! https://help.adblockplus.org/hc/articles/360062733293-How-to-write-filters
! Unwanted or bandwidth draining resources
$font
$media
$object
$other
$ping
$subdocument
$webrtc
##audio
##video
##track
##embed:not([src="about:blank"][type="application/pdf"])
##noembed
##frameset
##frame
~mail.proton.me,~docs.proton.me,~drive.proton.me##iframe:not([src^="https://challenges.cloudflare.com/"]):not([src^="https://www.recaptcha.net/recaptcha/"]):not([src^="https://www.google.com/recaptcha/"]):not([src^="https://newassets.hcaptcha.com/captcha/"]):not([src^="chrome-extension://ghmbeldphafepmbegfdlkpapadhbakde/"])
##fencedframe
##noframes
##object
google.com
youtube.com
vimeo.com
! EXPERIMENTAL
$websocket,third-party
$xhr,third-party
! General exceptions
@@||challenges.cloudflare.com^$subdocument
@@||www.recaptcha.net/recaptcha/api2/anchor^$subdocument
@@||www.google.com/recaptcha/api2/anchor^$subdocument
@@||newassets.hcaptcha.com/captcha/^$subdocument
@@||search.brave.com^$font,other
@@||dash.cloudflare.com^$subdocument,other
@@github.com^$other
@@||github.githubassets.com^$other,domain=github.com
@@||productionresults*.blob.core.windows.net/actions-results/$xhr,domain=github.com
@@||viewscreen.githubusercontent.com^$subdocument,domain=github.com
@@||gitlab.com^$other
@@||chat.deepseek.com^$other
@@||claude.ai^$other
@@||www.claudeusercontent.com^$subdocument,domain=claude.ai
@@manuscdn.com/sessionFile/$xhr,domain=manus.im
@@||session.getmerlin.in^$xhr,domain=www.getmerlin.in
@@||data.chainguard.dev/query^$xhr,domain=console.chainguard.dev|images.chainguard.dev
@@||token.chainguard.dev^$subdocument,domain=console.chainguard.dev
@@||hoppscotch.io^$other
@@||api.hoppscotch.io/graphql^$websocket,domain=hoppscotch.io
@@||firestore.googleapis.com/google.firestore.v1.Firestore/$xhr,ping,domain=hoppscotch.io
@@||identitytoolkit.googleapis.com/v1/$xhr,domain=hoppscotch.io
@@||www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig$xhr,domain=postwoman-api.firebaseapp.com
! Development exceptions
@@localhost:3000^
@@localhost:5000^
@@||rsms.me/inter/font-files$font,domain=localhost|bugbox.local|listensync.local
@@||fonts.gstatic.com/s/$font,domain=localhost
@@accessplz.local^
@@bugbox.local^
@@listensync.local^
! TODO: Remove once service is deployed in production
||io.bugbox.app/v0/*.js$script,redirect=noop.js
! Proton apps
@@proton.me^$other
@@proton.me/crypto-worker.*.js$script
@@||account.proton.me/storage.html$subdocument,domain=proton.me
@@||docs-editor.proton.me^$subdocument,domain=docs.proton.me
@@||pass-api.proton.me/api/$xhr
drive.proton.me#@#object
drive.proton.me#@#video
mail.proton.me#@#object
! Other exceptions (uncomment when necessary)
!@@||pro.kraken.com^$other
!@@||lodgeit.net.au$font,other
!@@xero.com^$other
! Sonetel
!||accounts.google.com/gsi/client^$script,domain=app.sonetel.com,redirect=user-gsi.js
!@@||app.sonetel.com^$other
!@@||msg.sonetel.com/ws-xmpp^$websocket,domain=app.sonetel.com
! Shopify
!@@||admin.shopify.com^$other
!@@||cdn.shopify.com^$domain=admin.shopify.com
! DSL
!gtm.dropshiplifestyle.com
!@@||player.vimeo.com$subdocument,domain=blueprint.dropshiplifestyle.com
!@@||player.vimeo.com/api/player.js$domain=blueprint.dropshiplifestyle.com
!@@||player.vimeo.com/video$domain=blueprint.dropshiplifestyle.com
!player.vimeo.com#@#video
! Movie Box Pro
!www.movieboxpro.app#@#video
!@@shegu.net$domain=www.movieboxpro.app,media
! ABC iview
!@@iview.abc.net.au$media,other
!iview.abc.net.au#@#video
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AdBlock Rule Test Page</title>
<style>
body {
font-family: ui-sans-serif, system-ui, sans-serif;
line-height: 1.6;
max-width: 800px;
margin: 0 auto;
padding: 20px;
color: #333;
}
h1, h2, h3 {
color: #2c3e50;
}
a{
word-break: break-word;
overflow-wrap: break-word;
white-space: normal;
}
iframe {
width: 100%;
height: 150px;
border: 1px solid #ccc;
display: block;
margin-bottom: 10px;
}
button {
background-color: #194ac6;
border: none;
color: white;
padding: 10px 15px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
}
.test-section {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
background-color: #f9f9f9;
}
.test-container {
margin-bottom: 20px;
}
.test-container > h3 {
margin-top: 0;
margin-bottom: 0.5em;
}
.info {
font-size: 14px;
color: #666;
margin-bottom: 5px;
}
.status {
padding: 5px 10px;
border-radius: 4px;
font-size: 14px;
display: inline-block;
margin-top: 5px;
}
.loaded {
background-color: #d4edda;
color: #155724;
}
.blocked {
background-color: #f8d7da;
color: #721c24;
}
</style>
<script src=https://io.bugbox.app/v0/bugbox.js crossorigin data-key=AZafrexVcACPUC_DEVhZDw data-release=1.0.0></script>
</head>
<body>
<h1>AdBlock Rule Test Page</h1>
<p>This page allows you to test various AdBlock rules, particularly those targeting subdocuments (iframes).</p>
<div class="test-section">
<h2>Custom AdBlock Rules</h2>
<p>Get the custom rules from <a href="https://gist.github.com/maxmilton/8f352d731a40e6deacda043ec84b8be3" target="_blank">gist.github.com/maxmilton/8f352d731a40e6deacda043ec84b8be3</a> or <code>brave-adblock-rules.txt</code>, add them in <a href="brave://adblock" target="_blank">brave://adblock</a>, and then reload this page.</p>
<p>NOTE: Frames should both have their network requests blocked <em>and</em> be visually hidden.</p>
</div>
<div class="test-section">
<h2>Iframe Tests</h2>
<div class="test-container">
<h3>1. Blank Iframe</h3>
<div class="info">Source: <code>about:blank</code><br>Expect: <em>empty + hidden</em></div>
<iframe src="about:blank" id="blank1-iframe"></iframe>
<div id="blank1-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>2. Blank Iframe</h3>
<div class="info">Source: <code>undefined</code> (no src attribute; defaults to about:blank)<br>Expect: <em>empty + hidden</em></div>
<iframe id="blank2-iframe"></iframe>
<div id="blank2-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>3. Local Browser Resource Iframe</h3>
<div class="info">Source: <code>about://version</code><br>Expect: <em>empty + hidden</em></div>
<iframe src="about://version" id="local1-iframe"></iframe>
<div id="local1-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>4. Local HTML Document Iframe</h3>
<div class="info">Source: <code>/local.html</code><br>Expect: <em>empty + hidden</em></div>
<iframe src="/local.html" id="local2-iframe"></iframe>
<div id="local2-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>5. Local Image File Iframe</h3>
<div class="info">Source: <code>/favicon.ico</code><br>Expect: <em>empty + hidden</em></div>
<iframe src="/favicon.ico" id="local3-iframe"></iframe>
<div id="local3-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>6. Inline HTML Iframe</h3>
<div class="info">Source: <code>srcdoc inlined html</code><br>Expect: <em>empty + hidden</em></div>
<iframe srcdoc="<h1>Failed: Should Not Visible!</h1>" id="inline1-iframe"></iframe>
<div id="inline1-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>7. Inline Image Iframe</h3>
<div class="info">Source: <code>srcdoc inline img</code><br>Expect: <em>empty + hidden</em></div>
<iframe srcdoc="<img src='/favicon.ico' />" id="inline2-iframe"></iframe>
<div id="inline2-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>8. Regular Iframe</h3>
<div class="info">Source: <code>https://example.com</code><br>Expect: <em>blocked + hidden</em></div>
<iframe src="https://example.com" id="regular-iframe"></iframe>
<div id="regular-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>9. Cloudflare Challenges Iframe</h3>
<div class="info">Source: <code>https://challenges.cloudflare.com</code><br>Expect: <em>allowed + hidden</em></div>
<iframe src="https://challenges.cloudflare.com" id="cloudflare-iframe"></iframe>
<div id="cloudflare-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>10. Google Iframe</h3>
<div class="info">Source: <code>https://www.google.com</code><br>Expect: <em>blocked + hidden</em></div>
<iframe src="https://www.google.com" id="google-iframe"></iframe>
<div id="google-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>11. Protonmail Iframe</h3>
<div class="info">Source: <code>https://mail.proton.me/</code><br>Expect: <em>blocked + hidden</em></div>
<iframe src="https://mail.proton.me/" id="protonmail-iframe"></iframe>
<div id="protonmail-status" class="status">Checking status...</div>
</div>
</div>
<div class="test-section">
<h2>Script-Generated Iframe Test</h2>
<div class="test-container">
<h3>1. Dynamic Iframe Creation</h3>
<div class="info">Source: <code>https://www.bing.com</code><br>Expect: <em>blocked + hidden</em></div>
<button id="create-iframe">Create Dynamic Iframe</button>
<div id="dynamic-test-container"></div>
<div id="dynamic-status" class="status">Click button to test</div>
</div>
</div>
<div class="test-section">
<h2>Cloudflare Turnstile Test</h2>
<div class="test-container">
<h3>1. Turnstile Challenge</h3>
<div class="info">Source: Explicitly rendered Cloudflare Turnstile challenge<br>Expect: <em>allowed + shown</em></div>
<div id="turnstile-container"></div>
<div id="turnstile-status" class="status">Checking status...</div>
<div id="turnstile-status2" class="status"></div>
</div>
</div>
<div class="test-section">
<h2>Google reCAPTCHA Test</h2>
<div class="test-container">
<h3>1. reCAPTCHA Challenge</h3>
<div class="info">Source: Explicitly rendered Google reCAPTCHA challenge<br>Expect: <em>allowed + shown</em></div>
<div id="recaptcha-container"></div>
<div id="recaptcha-status" class="status">Checking status...</div>
<div id="recaptcha-status2" class="status"></div>
</div>
</div>
<script>
// Function to check if iframe loaded successfully
function checkIframeStatus(iframeId, statusId) {
const iframe = document.getElementById(iframeId);
const statusElement = document.getElementById(statusId);
try {
// Try to access the iframe content - will throw error if blocked
setTimeout(() => {
try {
// This will throw an error if the iframe is cross-origin
// but loaded, or if it's completely blocked
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
// If we get here, it's likely same-origin and loaded
if (iframeDoc.documentElement.outerHTML === '<html><head></head><body></body></html>') {
statusElement.textContent = "Loaded, but empty";
statusElement.className = "status loaded";
} else {
statusElement.textContent = "Loaded";
statusElement.className = "status loaded";
}
} catch (error) {
// Check if iframe has a src attribute with content
if (iframe.getAttribute('src') && iframe.getAttribute('src') !== 'about:blank') {
// We can use offsetHeight as a rough indicator
if (iframe.offsetHeight > 0) {
statusElement.textContent = "Likely loaded (cross-origin)";
statusElement.className = "status loaded";
} else {
statusElement.textContent = "Blocked or Failed to Load";
statusElement.className = "status blocked";
}
} else {
statusElement.textContent = "Blocked or Failed to Load";
statusElement.className = "status blocked";
}
}
}, 2000); // Wait 2 seconds to check status
} catch (error) {
statusElement.textContent = "Blocked or Failed to Load";
statusElement.className = "status blocked";
}
}
// Check all iframes
window.onload = function () {
checkIframeStatus('blank1-iframe', 'blank1-status');
checkIframeStatus('blank2-iframe', 'blank2-status');
checkIframeStatus('local1-iframe', 'local1-status');
checkIframeStatus('local2-iframe', 'local2-status');
checkIframeStatus('local3-iframe', 'local3-status');
checkIframeStatus('inline1-iframe', 'inline1-status');
checkIframeStatus('inline2-iframe', 'inline2-status');
checkIframeStatus('regular-iframe', 'regular-status');
checkIframeStatus('cloudflare-iframe', 'cloudflare-status');
checkIframeStatus('google-iframe', 'google-status');
checkIframeStatus('protonmail-iframe', 'protonmail-status');
// Setup dynamic iframe creation
document.getElementById('create-iframe').addEventListener('click', function() {
const container = document.getElementById('dynamic-test-container');
container.innerHTML = ''; // Clear previous
const iframe = document.createElement('iframe');
iframe.src = 'https://www.bing.com';
iframe.id = 'dynamic-iframe';
container.appendChild(iframe);
const statusElement = document.getElementById('dynamic-status');
statusElement.textContent = 'Checking status...';
statusElement.className = 'status';
setTimeout(() => {
checkIframeStatus('dynamic-iframe', 'dynamic-status');
}, 500);
});
};
</script>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"></script>
<script>
if ('turnstile' in window) {
turnstile.ready(function () {
const statusElement = document.getElementById('turnstile-status');
const statusElement2 = document.getElementById('turnstile-status2');
try {
// https://developers.cloudflare.com/turnstile/troubleshooting/testing/
const token = turnstile.render("#turnstile-container", {
sitekey: "3x00000000000000000000FF", // dummy test key to force an interactive challenge
'error-callback': function (error) {
// https://developers.cloudflare.com/turnstile/troubleshooting/client-side-errors/error-codes/
statusElement2.textContent = "Loaded, but error: " + error;
statusElement2.className = "status blocked";
},
'unsupported-callback': function () {
statusElement2.textContent = "Loaded, but unsupported";
statusElement2.className = "status blocked";
},
'expired-callback': function () {
statusElement2.textContent = "Loaded, but token expired";
statusElement2.className = "status loaded";
},
'timeout-callback': function () {
statusElement2.textContent = "Loaded, but timed out";
statusElement2.className = "status loaded";
},
});
statusElement.textContent = `Loaded, token: ${token}`;
statusElement.className = "status loaded";
} catch (error) {
statusElement.textContent = "Blocked or Failed to Load";
statusElement.className = "status blocked";
}
});
} else {
const statusElement = document.getElementById('turnstile-status');
statusElement.textContent = "Blocked or Failed to Load";
statusElement.className = "status blocked";
}
</script>
<!-- <script src="https://www.google.com/recaptcha/api.js?render=explicit"></script> -->
<script src="https://www.recaptcha.net/recaptcha/api.js?render=explicit"></script>
<script>
if ('grecaptcha' in window) {
grecaptcha.ready(function () {
const statusElement = document.getElementById('recaptcha-status');
const statusElement2 = document.getElementById('recaptcha-status2');
try {
grecaptcha.render("recaptcha-container", {
sitekey: "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI", // dummy test key
'error-callback': function (error) {
statusElement2.textContent = "Loaded, but error: " + error;
statusElement2.className = "status blocked";
},
'expired-callback': function () {
statusElement2.textContent = "Loaded, but response expired";
statusElement2.className = "status loaded";
},
});
statusElement.textContent = 'Loaded';
statusElement.className = "status loaded";
} catch (error) {
statusElement.textContent = "Blocked or Failed to Load";
statusElement.className = "status blocked";
}
});
} else {
const statusElement = document.getElementById('recaptcha-status');
statusElement.textContent = "Blocked or Failed to Load";
statusElement.className = "status blocked";
}
</script>
</body>
</html>
(function () {
'use strict';
const noop = () => {};
((globalThis.google ??= {}).accounts ??= {}).id ??= {
initialize: noop,
renderButton: noop,
disableAutoSelect: noop,
};
})();
#!/bin/sh
set -eu
script_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)
if ! test -f "${script_dir}/favicon.ico"; then
# Create minimal favicon.ico file
magick -size 16x16 xc:red -strip -colors 1 -depth 2 "${script_dir}/favicon.ico"
fi
url='http://localhost:5000/adblock-test.html'
xdg-open "$url" 2>/dev/null || echo "Open URL: $url"
exec busybox httpd -fvv -p '127.0.0.1:5000' -h "$script_dir"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AdBlock Rule Test Page</title>
<style>
body {
font-family: 'ui-sans-serif', 'system-ui', 'sans-serif';
line-height: 1.6;
max-width: 800px;
margin: 0;
padding: 0 20px;
color: #f8d7da;
background-color: #721c24;
}
h1 {
margin-top: 0;
}
</style>
</head>
<body>
<h1>Failed: Should Not Visible!</h1>
<p>This file is used to test local frames are blocked by AdBlock rules. It should not be visible if the adblock rules are working correctly.</p>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment