Initial commit
This commit is contained in:
commit
e90ff542b0
8 changed files with 250 additions and 0 deletions
7
README
Normal file
7
README
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Cloudflare Blocker extension
|
||||
|
||||
* Detects Cloudflare-related headers in outgoing requests.
|
||||
* Blocks the request if Cloudflare is present.
|
||||
* Toggle the blocker on/off via the extension popup.
|
||||
|
||||
Available from Mozilla Add-ons: [https://addons.mozilla.org/en-US/firefox/addon/cloudflare-blocker/](https://addons.mozilla.org/en-US/firefox/addon/cloudflare-blocker/)
|
||||
69
background.js
Normal file
69
background.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
let blockingEnabled = true;
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'toggleBlocking') {
|
||||
blockingEnabled = message.enabled;
|
||||
}
|
||||
|
||||
if (message.action === 'getBlockingState') {
|
||||
sendResponse({ action: 'setBlockingState', enabled: blockingEnabled });
|
||||
}
|
||||
});
|
||||
|
||||
chrome.webRequest.onHeadersReceived.addListener(
|
||||
function(details) {
|
||||
if (!blockingEnabled) {
|
||||
return { cancel: false };
|
||||
}
|
||||
|
||||
// These are Cloudflare's headers, taken from here:
|
||||
// https://developers.cloudflare.com/fundamentals/reference/http-headers/
|
||||
const cloudflare_headers = [
|
||||
'cf-connecting-ip',
|
||||
'cf-connecting-ipv6',
|
||||
'cf-ew-via',
|
||||
'cf-Pseudo-ipv4',
|
||||
'cf-ray',
|
||||
'cf-ipcountry',
|
||||
'cf-visitor',
|
||||
'cf-worker'
|
||||
];
|
||||
// You might want capture all headers prefixed with "cf-":
|
||||
// const cf_header = details.responseHeaders.find(header =>
|
||||
// header.name.toLowerCase().startsWith('cf-')
|
||||
// );
|
||||
|
||||
const cf_header = details.responseHeaders.find(header =>
|
||||
cloudflare_headers.includes(header.name.toLowerCase())
|
||||
);
|
||||
|
||||
if (cf_header) {
|
||||
console.log('Cloudflare header found:', cf_header);
|
||||
|
||||
const query_params = new URLSearchParams({
|
||||
name: cf_header.name,
|
||||
value: cf_header.value,
|
||||
url: details.url
|
||||
}).toString();
|
||||
|
||||
/*
|
||||
* It would be cool to pass the tab URL in the query params, but how?
|
||||
* When accessing chrome.tabs here, the active tab URL is "about:newtab".
|
||||
* Because we block the request immediately and the tab URL state doesn't
|
||||
* never update to the URL we tried to access. I'd like to pass the URL
|
||||
* to the web.archive.org/tab_url_here in blocked.html.
|
||||
* Email contact@libroot.org if you know a solution!
|
||||
*/
|
||||
|
||||
// Redirect to our custom blocked.html page
|
||||
const url = chrome.runtime.getURL('blocked.html') + '?' + query_params;
|
||||
console.log('Redirecting to blocked page:', url);
|
||||
chrome.tabs.update(details.tabId, { url: url });
|
||||
|
||||
// Block the request, reject Cloudflare!
|
||||
return { cancel: true };
|
||||
}
|
||||
},
|
||||
{ urls: ['<all_urls>'] },
|
||||
['blocking', 'responseHeaders']
|
||||
);
|
||||
40
blocked.html
Normal file
40
blocked.html
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cloudflare page blocked</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
color: red;
|
||||
}
|
||||
a {
|
||||
color: blue;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>This page has been blocked by the Cloudflare Blocker extension due to a Cloudflare header.</h1>
|
||||
|
||||
<p>
|
||||
<strong>Blocked Header:</strong>
|
||||
<pre id="header_info">Loading...</pre>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Blocked response URL:</strong>
|
||||
<pre id="url">Loading...</pre>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<p>You can probably view the page on the <a href="https://web.archive.org" target="_blank">Wayback Machine</a>.</p>
|
||||
|
||||
<script src="blocked.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
21
blocked.js
Normal file
21
blocked.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
function getUrlParams() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return {
|
||||
name: urlParams.get('name'),
|
||||
value: urlParams.get('value'),
|
||||
url: urlParams.get('url')
|
||||
};
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const params = getUrlParams();
|
||||
|
||||
if (params.name && params.value) {
|
||||
const header_info = `Name: ${params.name}\nValue: ${params.value}`;
|
||||
document.getElementById('header_info').textContent = header_info;
|
||||
}
|
||||
|
||||
if (params.url) {
|
||||
document.getElementById('url').textContent = params.url;
|
||||
}
|
||||
});
|
||||
BIN
icons/icon.png
Normal file
BIN
icons/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
28
manifest.json
Normal file
28
manifest.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "Cloudflare Blocker",
|
||||
"version": "1.0.0",
|
||||
"author": "libroot.org",
|
||||
"developer": {
|
||||
"name": "libroot",
|
||||
"url": "https://libroot.org/posts/Cloudflare-Blocker-Firefox-extension"
|
||||
},
|
||||
"description": "Blocks requests if they have Cloudflare's headers, and shows a blocked page.",
|
||||
"manifest_version": 2,
|
||||
"permissions": [
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"tabs",
|
||||
"<all_urls>"
|
||||
],
|
||||
"background": {
|
||||
"scripts": ["background.js"],
|
||||
"persistent": false
|
||||
},
|
||||
"browser_action": {
|
||||
"default_popup": "popup.html",
|
||||
"default_icon": "icons/icon.png"
|
||||
},
|
||||
"web_accessible_resources": [
|
||||
"blocked.html"
|
||||
]
|
||||
}
|
||||
53
popup.html
Normal file
53
popup.html
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cloudflare Blocker</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 10px;
|
||||
width: 200px;
|
||||
}
|
||||
#toggle {
|
||||
width: 50px;
|
||||
height: 25px;
|
||||
position: relative;
|
||||
border-radius: 15px;
|
||||
background-color: #ccc;
|
||||
cursor: pointer;
|
||||
}
|
||||
#toggle .slider {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
#toggle.active {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
#toggle.active .slider {
|
||||
left: 25px;
|
||||
}
|
||||
#status {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h3>Cloudflare Blocker</h3>
|
||||
<div id="toggle" class="active">
|
||||
<div class="slider"></div>
|
||||
</div>
|
||||
<p id="status">Blocking is ON</p>
|
||||
<script src="popup.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
32
popup.js
Normal file
32
popup.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
const toggle = document.getElementById('toggle');
|
||||
const status = document.getElementById('status');
|
||||
|
||||
chrome.runtime.sendMessage({ action: 'getBlockingState' }, (response) => {
|
||||
if (response && response.enabled !== undefined) {
|
||||
const blockingEnabled = response.enabled;
|
||||
|
||||
if (blockingEnabled) {
|
||||
toggle.classList.add('active');
|
||||
status.textContent = 'Blocking is ON';
|
||||
} else {
|
||||
toggle.classList.remove('active');
|
||||
status.textContent = 'Blocking is OFF';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
toggle.addEventListener('click', function () {
|
||||
const isActive = toggle.classList.toggle('active');
|
||||
|
||||
if (isActive) {
|
||||
status.textContent = 'Blocking is ON';
|
||||
} else {
|
||||
status.textContent = 'Blocking is OFF';
|
||||
}
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'toggleBlocking',
|
||||
enabled: isActive
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue