Is Youtube Unblocked safe?
Youtube Unblocked is high risk. Clicking Unblock installs a Chrome PAC script routing matching sites through a proxy chosen via config from auth.unblockd.org. Free mode matches YouTube, Google media/CDN hosts, browsebetter.io; Speed/Quantum mode routes every destination.
Who publishes itValueFoundry - 1 other listing from the same operator, none carrying a finding
ValueFoundry - 1 other listing from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
1 other listing published from this account, 1k+ users between them, none of them carrying a finding.
Shared hosts - 2 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Proxy Routing Through browsebetter.io
Clicking Unblock installs a Chrome PAC script routing matching sites through a proxy chosen via config from auth.unblockd.org.
Free mode matches YouTube, Google media/CDN hosts, browsebetter.io; Speed/Quantum mode routes every destination.
You click Unblock in the extension popup.
The popup either uses a paid-plan default site or the site you entered for unblocking.
The extension installs browser proxy rules and sends matching browsing through the selected proxy.
For Speed and Quantum plans, the generated rule returns the proxy before checking the destination host.
| Field | Value | Why it matters | |
|---|---|---|---|
Browsing destination | https://www.youtube.com/watch?v=dQw4w9WgXcQ | Shows which site you're trying to reach when routed through the proxy. Even on encrypted pages, the destination host is exposed as metadata. | |
Configured site | https://www.google.com/ | If you choose a site to unblock, that host is added to the proxy rule list. | |
Request metadata | CONNECT www.youtube.com:443 HTTP/1.1 | A proxy route receives browser request metadata needed to forward the connection, such as the method and destination host. | |
Plan tier | Speed | The plan tier changes the routing scope. Speed and Quantum mode route every destination through the selected proxy. |
These stored values decide whether the proxy is enabled, which site joins the rule list, and whether the paid all-destination branch runs.
chrome.storage values used by popup.js and background.js{
"plan_details": "Speed, Quantum, or a non-paid value",
"proxyEnabled": "true 12345.678",
"proxySuccess": "Works 12352.441 after the connectivity check succeeds",
"custom_website": "https://www.google.com/ or a user-entered valid URL"
}Popup, background, PAC, credential, and connectivity code paths
window.onload = function()
{
check_paid();
var message = chrome.i18n.getMessage("heading");
if(message && message != undefined && message != null && message != "" && message != " ")
{
document.getElementById("h1").innerHTML = message;
}
var message2 = chrome.i18n.getMessage("cta");
if(message2 && message2 != undefined && message2 != null && message2 != "" && message2 != " ")
{
document.getElementById("unblock").innerHTML = message2 + `<span id="paidlines"> The Web</span><img src="images/64.png" id="icon">`;
}
var message3 = chrome.i18n.getMessage("maytake");
if(message3 && message3 != undefined && message3 != null && message3 != "" && message3 != " ")
{
document.getElementById("maytake").innerHTML = message3;
}
initializ(); //fetch, update FE
document.getElementById('unblock').addEventListener('click', toggl); //listen
document.getElementById("activate").addEventListener("click", activate);
check_key0()
};function toggl()
{
// iterate (toggle) > update BE, update FE
var done = 0; //api may return no data
chrome.proxy.settings.get({}, function(config)
{
console.log('Proxy configuration:', config);
// You can now check the `config` object to see if a proxy is set
Object.getOwnPropertyNames(config).forEach(key =>
{
console.log(key, config[key]);
/*
if(config[key] == "controlled_by_other_extensions")
{
//off hi hoga, on possible b nhi h, off hi rahega, no changes FE or BE
alert("Please turn off other website-unblocking browser extensions.");
done = 1;
return;
}*/
if(config[key].pacScript)
{
if(config[key].pacScript.data)
{
if(config[key].pacScript.data.indexOf("no.youtubeunblocked.notld") != -1)
{
//ON hai ---> OFF krde (toggle 1)
//update BE, update FE
done = 1; //flag
console.log("off");
chrome.storage.sync.set({ proxyEnabled: "false " + performance.now() }); //update BE, false
var message2 = chrome.i18n.getMessage("cta");
if(message2 && message2 != undefined && message2 != null && message2 != "" && message2 != " ")
{
document.getElementById("unblock").innerHTML = message2 + `<span id="paidlines"> The Web</span><img src="images/64.png" id="icon">`;
}
else
{
document.getElementById("unblock").innerHTML = `Unblock <span id="paidlines"> The Web</span><img src="images/64.png" id="icon">`; //FE1
}
document.getElementById("unblock").className = ""; //FE2, just in case
document.body.id = "OFF"; //FE3
return;
}
}
}
});
if(done === 0)
{
//came out of the loop without returning
//OFF hai --> ON krde (toggle 2)
//update BE, update FE
//check first
if(document.body.getAttribute("plan") == "paid")
{
chrome.storage.local.set({ "custom_website" : "https://www.google.com/" }).then(() =>
{
console.log("Value set");
console.log("on");
chrome.storage.sync.set({ proxyEnabled: "true " + performance.now() }); //BE
var message2 = chrome.i18n.getMessage("progress");
if(message2 && message2 != undefined && message2 != null && message2 != "" && message2 != " ")
{
document.getElementById("unblock").innerHTML = message2;
}
else
{
document.getElementById("unblock").innerHTML = "Unblocking Access..."; //FE1, can also be Revert Unblocking
}
document.getElementById("unblock").className = "noclick"; //FE2
document.body.id = "ON"; //FE3
});
}
else if(isValidURL(document.getElementById("website").value))
{
chrome.storage.local.set({ "custom_website" : document.getElementById("website").value }).then(() =>
{
console.log("Value set");
console.log("on");
chrome.storage.sync.set({ proxyEnabled: "true " + performance.now() }); //BE
var message2 = chrome.i18n.getMessage("progress");
if(message2 && message2 != undefined && message2 != null && message2 != "" && message2 != " ")
{
document.getElementById("unblock").innerHTML = message2;
}
else
{
document.getElementById("unblock").innerHTML = "Unblocking Access..."; //FE1, can also be Revert Unblocking
}
document.getElementById("unblock").className = "noclick"; //FE2
document.body.id = "ON"; //FE3
});
}
else
{
var alrt = chrome.i18n.getMessage("misc_alert2");
if(alrt && alrt != undefined && alrt != null && alrt != "" && alrt != " ")
{
alert(alrt);
}
else
{
alert("Please enter a valid URL, and make sure that the URL starts with https://");
}
return;
}
return;
}
});
};chrome.storage.onChanged.addListener(changes => {
if (changes.proxyEnabled && (changes.proxyEnabled.newValue != changes.proxyEnabled.oldValue)) //changes happened + not same value
{
if (timerTime) {
timerTime = 12000;
}
Promise.resolve(setIPs()).then(() => check_custom(proxyList[0], changes.proxyEnabled.newValue));
// setIPs();
// check_custom(proxyList[0], changes.proxyEnabled.newValue);
; //switch, check/set url first
}
else if (changes.plan_details && (changes.plan_details.newValue != changes.plan_details.oldValue)) {
refresh_plan(); //plan change possible
}
else if (changes.key && (changes.key.newValue != changes.key.oldValue)) {
//console.log("Key changed to: " + changes.key.newValue);
check_key(changes.key.newValue);
// Do something with the new key if needed
}
});async function updateProxy(proxy, toggle_val) {
//active_ip = proxy;
if (toggle_val.indexOf("true") != -1 || toggle_val === true /*&& toggle_val != "false" && toggle_val != "null" && toggle_val != "undefined" && toggle_val != ""*/) {
//if == -1, not found
//if != -1, found (true)
try {
await setupOffscreenDocument('off_screen.html');
}
catch (error) {
console.log(error);
}
var i = 0;
var strr = "";
for (i = 0; i < unblocklist2.length; i++) {
if (strr == "") //first
{
strr = strr + `dnsDomainIs(host, '${unblocklist2[i]}')`;
}
else //first + n, till last
{
strr = strr + ` || dnsDomainIs(host, '${unblocklist2[i]}')`;
}
}
chrome.storage.local.get(["plan_details"]).then((result) => {
var pacScript;
if (result.plan_details == "Speed" || result.plan_details == "Quantum") {
pacScript = `
function FindProxyForURL(url, host)
{
return 'PROXY ${proxy}';
if(`+ strr + `)
{
return 'PROXY ${proxy}';
}
else
{
return 'DIRECT';
}
}
`;
}
else {
pacScript = `
function FindProxyForURL(url, host)
{
if(`+ strr + `)
{
return 'PROXY ${proxy}';
}
else
{
return 'DIRECT';
}
}
`;
}
console.log(pacScript);
/*
var pacScript = `
function FindProxyForURL(url, host)
{
var i = 0;
for(i=0; i < ${unblocklist2}.length; i++)
{
if(dnsDomainIs(host, '${unblocklist2}[i]'))
{
return 'PROXY ${proxy}';
}
else if(i == ${unblocklist2}.length - 1)
{
return 'DIRECT';
}
}
}
`;
console.log(pacScript);
*/
/*
var pacScript = `
function FindProxyForURL(url, host)
{
if
(
dnsDomainIs(host, 'whatismyipaddress.com') ||
dnsDomainIs(host, 's3.browsebetter.io') || dnsDomainIs(host, 'browsebetter.io') ||
dnsDomainIs(host, 'unblockedgames76.co') || dnsDomainIs(host, 'www.unblockedgames76.co') ||
dnsDomainIs(host, 'gamepix.com') || dnsDomainIs(host, 'play.gamepix.com') || dnsDomainIs(host, 'www.gamepix.com') || dnsDomainIs(host, 'api.h5.gamepix.com') || dnsDomainIs(host, 'games.assets.gamepix.com') || dnsDomainIs(host, 'games.builds.gamepix.com') ||
dnsDomainIs(host, 'iubenda.com') || dnsDomainIs(host, 'cdn.iubenda.com') || dnsDomainIs(host, 'cs.iubenda.com')
)
{
return 'PROXY ${proxy}';
}
else
{
return 'DIRECT';
}
}
`;
*/
chrome.proxy.settings.set
({
value:
{
mode: "pac_script",
pacScript:
{
data: pacScript
}
},
scope: "regular"
},
function () {
console.log("Proxy set to: " + proxy);
testProxyConnectivity(proxy);
});
});
}
else {
//false, off
chrome.proxy.settings.clear({ scope: "regular" });
console.log("cleared");
}
};chrome.webRequest.onAuthRequired.addListener((details, callbackFn) => {
// Get credentials from cached config, or fetch if needed
(async () => {
let config = proxyConfig;
if (!config) {
console.log('Fetching proxy config for auth...');
config = await fetchProxyConfig();
}
if (!config) {
console.error('No proxy config available for auth');
callbackFn({});
return;
}
// Get actual plan from storage to select correct credentials
const result = await chrome.storage.local.get(["plan_details"]);
let creds;
if (result.plan_details == "Speed" && config.speed) {
creds = config.speed;
} else if (result.plan_details == "Quantum" && config.quantum) {
creds = config.quantum;
} else {
creds = config.free;
}
if (creds && creds.username && creds.password) {
callbackFn({
authCredentials: {
username: creds.username,
password: creds.password
}
});
} else {
console.error('No credentials found in config');
callbackFn({});
}
})();
},
{ urls: unblocklist },
['asyncBlocking']
);function testProxyConnectivity(proxy) {
try {
chrome.runtime.sendMessage({ action: 'forwardToWorker', data: "hi" });
}
catch (error) {
console.log(error);
}
var fetchPromise = fetch('https://s3.browsebetter.io/checkcors.html', { method: 'GET', cache: 'no-cache' }); // Use a reliable URL for testing
var timeoutPromise = new Promise((resolve, reject) => {
if (timerTime && timerTime >= 12000) //valid
{
setTimeout(() => reject("Timeout"), timerTime);
}
else {
setTimeout(() => reject("Timeout"), 12000); // 10 seconds timeout
}
});
Promise.race([fetchPromise, timeoutPromise])
.then(response => {
if (response.ok) {
console.log(`Success: Proxy ${proxy} is working.`);
if (customU != null && customU != undefined && customU != "") {
/*
if(customU == "youtube.com")
{
customU = "youtube.com/?s=1";
}
*/
chrome.storage.local.set({ "p1": Date.now() });
chrome.tabs.create({ url: "https://" + customU, selected: true });
}
//console.log(performance.now());
chrome.storage.sync.set({ proxySuccess: "Works " + performance.now() });
// Here you can do something with the working proxy
}
else {
console.log(`Failure: Proxy ${proxy} failed.`);
console.log(response);
nextProxy();
}
})
.catch(error => {
console.log(`Error or timeout with proxy ${proxy}: ${error}`);
nextProxy();
});
};chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// Handle proxy config fetch from background script
if (request.action === 'fetchProxyConfig') {
const BRIDGE_URL = 'https://auth.unblockd.org/v1/proxy/bridge';
// Create a promise to handle the async response
new Promise((resolve, reject) => {
const iframe = document.createElement('iframe');
iframe.src = BRIDGE_URL;
iframe.style.display = 'none';
document.body.appendChild(iframe);
const timer = setTimeout(() => {
cleanup();
reject(new Error('Timeout waiting for config from bridge'));
}, 5000);
const handler = (event) => {
if (event.origin !== 'https://auth.unblockd.org') return;
if (event.data && event.data.type === 'PROXY_CONFIG') {
cleanup();
resolve(event.data.payload);
}
};
window.addEventListener('message', handler);
function cleanup() {
window.removeEventListener('message', handler);
document.body.removeChild(iframe);
clearTimeout(timer);
}
})
.then(data => sendResponse({ success: true, data: data }))
.catch(error => sendResponse({ success: false, error: error.message }));
return true; // Keep message channel open for async response
}
if (request.action == 'forwardToWorker') {
try {
if (worker) {
worker.postMessage(request.data);
}
else {
renew(request.data);
}
}
catch (error) {
console.log(error);
renew(request.data);
}
}
});- auth.unblockd.org
The offscreen bridge returns proxy server lists and credentials used by the background code.
- s3.browsebetter.io
The extension tests connectivity with a GET request and includes this host in the PAC routing list.
- browsebetter.io
The base domain appears in the PAC routing list and the claim endpoint for the proxy infrastructure.
What it can do
Permissions this extension asks for, as declared in version 1.1.1. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Read and change your data on every site you visit
<all_urls>
Route all of your browsing through a server of its choosing
proxy
Store data in your browser
storage
Watch every request your browser makes
webRequest
Run hidden pages in the background
offscreen
Keep running in the background while your browser is open
background