Skip to content

Instantly share code, notes, and snippets.

@maxmilton
Last active April 3, 2025 06:25
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://help.eyeo.com/adblockplus/how-to-write-filters
! Unwanted or bandwidth draining resources
$font
$media
$object
$other
$ping
$subdocument
!$third-party
$webrtc
!$websocket
!$xmlhttprequest
##audio
##video
##track
##embed:not([src="about:blank"][type="application/pdf"])
##noembed
##frameset
##frame
##iframe:not([src="about:blank"]):not([src^="https://challenges.cloudflare.com/"]):not([src^="https://www.recaptcha.net/recaptcha/"]):not([src^="https://www.google.com/recaptcha/"])
##fencedframe
##noframes
google.com
youtube.com
vimeo.com
! General exceptions
@@||challenges.cloudflare.com^$subdocument
@@||www.recaptcha.net/recaptcha/api2/anchor^$subdocument
@@||www.google.com/recaptcha/api2/anchor^$subdocument
@@||search.brave.com^$font,other
@@github.com^$other
@@||chat.deepseek.com$other
! Development exceptions
@@localhost:3000
@@listensync.local
!@@||rsms.me/inter/font-files$domain=listensync.local|localhost,font
!@@||fonts.gstatic.com/s/$domain=localhost,font
!io.bugbox.app/v1/
! Other exceptions (uncomment when necessary)
!@@||pro.kraken.com^$other
!@@||lodgeit.net.au$font,other
!@@xero.com^$other
! Proton apps
@@proton.me^$other
@@proton.me/crypto-worker.*.js
@@||account.proton.me/storage.html$domain=proton.me,subdocument
@@||docs-editor.proton.me^$domain=docs.proton.me,subdocument
! DSL
!gtm.dropshiplifestyle.com
!@@||player.vimeo.com$domain=blueprint.dropshiplifestyle.com,subdocument
!@@||player.vimeo.com/api/player.js$domain=blueprint.dropshiplifestyle.com
!@@||player.vimeo.com/video$domain=blueprint.dropshiplifestyle.com
!player.vimeo.com#@#video
! Shopify
!@@||admin.shopify.com^$other
!@@||cdn.shopify.com^$domain=admin.shopify.com
! 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;
}
iframe {
width: 100%;
height: 150px;
border: 1px solid #ccc;
display: block;
margin-bottom: 10px;
}
button {
background-color: #4CAF50;
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;
}
.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>
</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>You can these rules: <a href="https://gist.github.com/maxmilton/8f352d731a40e6deacda043ec84b8be3" target="_blank">https://gist.github.com/maxmilton/8f352d731a40e6deacda043ec84b8be3</a>.</p>
<p>Add them in <a href="brave://adblock" target="_blank">brave://adblock</a> and 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 (should be allowed)</h3>
<div class="info">Source: about:blank</div>
<iframe src="about:blank" id="blank-iframe"></iframe>
<div id="blank-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>2. Local Browser Resource Iframe (should be blocked)</h3>
<div class="info">Source: about://version</div>
<iframe src="about://version" id="local1-iframe"></iframe>
<div id="local1-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>3. Local HTML Document Iframe (should be blocked)</h3>
<div class="info">Source: /local.html</div>
<iframe src="/local.html" id="local2-iframe"></iframe>
<div id="local2-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>4. Local Image File Iframe (should be blocked)</h3>
<div class="info">Source: /favicon.ico</div>
<iframe src="/favicon.ico" id="local3-iframe"></iframe>
<div id="local3-status" class="status">Checking status...</div>
</div>
<div class="test-container">
<h3>5. Regular Iframe (should be blocked)</h3>
<div class="info">Source: https://example.com</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>6. Cloudflare Challenges Iframe (should be allowed)</h3>
<div class="info">Source: https://challenges.cloudflare.com</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>7. Google Iframe (should be blocked)</h3>
<div class="info">Source: https://www.google.com</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>8. Protonmail Iframe (should be blocked)</h3>
<div class="info">Source: https://mail.proton.me/</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 Tests</h2>
<div class="test-container">
<h3>1. Dynamic Iframe Creation</h3>
<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">Explicitly rendered Cloudflare Turnstile challenge.</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>1. Google reCAPTCHA Test</h2>
<div class="info">Explicitly rendered Google reCAPTCHA challenge.</div>
<div id="recaptcha-container"></div>
<div id="recaptcha-status" class="status">Checking status...</div>
<div id="recaptcha-status2" class="status"></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('blank-iframe', 'blank-status');
checkIframeStatus('local1-iframe', 'local1-status');
checkIframeStatus('local2-iframe', 'local2-status');
checkIframeStatus('local3-iframe', 'local3-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", // 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>
#!/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 1x1 xc:none "${script_dir}/favicon.ico"
fi
xdg-open 'http://127.0.0.1:5000/adblock-test.html'
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