Is Unblocker for YouTube safe?
Unblocker for YouTube is medium risk. During popup login, the shipped code logs analytics events including the email entered or stored for the account, plus a persistent device ID, timestamp, and app version, sent to Amplitude's API, which was seen carrying this identifier.
Who publishes itRouteme LLC. - no other listings under this identity, 1 shared hostname
Routeme LLC. - no other listings under this identity, 1 shared hostname
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 1 hostname
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
Popup login analytics sends email and device ID to Amplitude
During popup login, the shipped code logs analytics events including the email entered or stored for the account, plus a persistent device ID, timestamp, and app version, sent to Amplitude's API, which was seen carrying this identifier.
You use the popup's premium login controls or choose to log out.
The relevant paths are the send-code, verify-code, login-failed, and logout handlers.
The extension builds an authentication analytics event that can include your email address.
The analytics helper adds a persistent device identifier and sends the event to Amplitude.
| Field | Value | Why it matters | |
|---|---|---|---|
Your email address | jordan.lee@example.com (illustrative) | This ties the popup login event to the account address you entered or had stored in the extension. | |
Authentication step | login_successful | This says which login action happened, such as requesting a code, completing login, failing login, or logging out. | |
Persistent device identifier | web_pybrl6xmmmrhlg9vb | This lets analytics events from the same browser profile be linked over time. | |
Session timestamp | 1720791446123 (illustrative) | This groups the event with other popup activity from the same browser session. | |
Extension platform and version | Chrome Extension / 4.0.0 | This describes the software environment that produced the event. |
| Accept | application/json |
| Content-Type | application/json |
Popup authentication events feed the Amplitude HTTP API
document.addEventListener('DOMContentLoaded', () => {
const emailForm = document.getElementById('email-form');
const codeForm = document.getElementById('code-form');
const emailInput = document.getElementById('email-input');
const sendCodeBtn = document.getElementById('send-code-btn');
const verificationCode = document.getElementById('verification-code');
const verifyCodeBtn = document.getElementById('verify-code-btn');
const haveCodeBtn = document.getElementById('have-code-btn');
// Email validation
emailInput.addEventListener('input', () => {
const isValidEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailInput.value);
sendCodeBtn.disabled = !isValidEmail;
});
// Handle email submission
sendCodeBtn.addEventListener('click', async () => {
amplitudeTracker.trackButtonClick("Send Code Button");
try {
// Add your API call here to send verification code
sendCode(emailInput.value, (data) => {
if(data.statusCode == 200){
amplitudeTracker.trackAuthEvent("code_sent", { email: emailInput.value, status: "success" });
showToast("Code sent to email", "success");
emailForm.classList.add('hidden');
codeForm.classList.remove('hidden');
chrome.storage.local.set({"YTU_EMAIL": emailInput.value});
chrome.storage.local.set({"YTU_CODE": "SEND"});
}
else if(data.statusCode == 201){
amplitudeTracker.trackAuthEvent("code_sent", { email: emailInput.value, status: "not_premium", error_code: data.statusCode });
showToast("Email address is not premium", "error");
}
else{
amplitudeTracker.trackAuthEvent("code_sent", { email: emailInput.value, status: "failed", error_code: data.statusCode });
showToast("(" + data.statusCode + ") Failed to send code", "error");
}
});
} catch (error) {
amplitudeTracker.trackError("code_send_error", error.message, { email: emailInput.value });
document.getElementById('email-error').textContent = error.message;
document.getElementById('email-error').style.display = 'block';
}
});
haveCodeBtn.onclick = () => {
amplitudeTracker.trackButtonClick("Have Code Button");
emailForm.classList.add('hidden');
codeForm.classList.remove('hidden');
}
// Handle verification code submission
verifyCodeBtn.addEventListener('click', async () => {
amplitudeTracker.trackButtonClick("Verify Code Button");
try {
const storageResult = await chrome.storage.local.get("YTU_EMAIL");
const email = storageResult["YTU_EMAIL"];
verifyCode(email, verificationCode.value, (data) => {
if(data.statusCode == 200){
userEmail = email;
amplitudeTracker.trackAuthEvent("login_successful", { email: email });
amplitudeTracker.setUserId(email);
showToast("Login successful", "success");
chrome.storage.local.set({"YTU_CODE": "VERIFY"});
showPage(false,"login-page")
checkPremium();
sendConnectionStatusToServiceWorker("disconnect");
}
else{
amplitudeTracker.trackAuthEvent("login_failed", { email: email, error_code: data.statusCode });
showToast("Failed to login", "error");
}
});
} catch (error) {
amplitudeTracker.trackError("verification_error", error.message, { email: email });
showToast("Something went wrong", "error");
}
});
});
document.getElementById('logout-btn').onclick = () => {
amplitudeTracker.trackButtonClick("Logout Button");
showAreYouSure(true,"Are you sure you want to logout?<br>Your Subscription remain active but this extension will back to free plan.<br>You can login again anytime.",(isSure) => {
if(isSure){
amplitudeTracker.trackAuthEvent("logout", { email: userEmail });
chrome.storage.local.set({"YTU_CODE": ""});
chrome.storage.local.set({"YTU_EMAIL": ""});
showToast("Logged out successfully", "success");
checkPremium();
sendConnectionStatusToServiceWorker("disconnect");
}
else{
showAreYouSure(false,"",() => {});
}
});
}const AMPLITUDE_API_KEY = '680812b42b998d072fd8d2ddf1f2aa70';
const AMPLITUDE_SECRET_KEY = '36c8e4734f7608aacca72929bd21dd9a';
const AMPLITUDE_PROJECT_ID = '727399';
class AmplitudeTracker {
constructor() {
this.deviceId = this.generateDeviceId();
this.sessionId = this.generateSessionId();
this.userId = null;
this.userProperties = {};
}
// Generate a unique device ID
generateDeviceId() {
let deviceId = localStorage.getItem('amplitude_device_id');
if (!deviceId) {
deviceId = 'web_' + Math.random().toString(36).substr(2, 9) + Date.now().toString(36);
localStorage.setItem('amplitude_device_id', deviceId);
}
return deviceId;
}
// Generate a unique session ID
generateSessionId() {
return Date.now();
}
// Set user ID when user logs in
setUserId(userId) {
this.userId = userId;
}
// Set user properties
setUserProperties(properties) {
this.userProperties = { ...this.userProperties, ...properties };
}
// Track an event
async trackEvent(eventType, eventProperties = {}) {
const event = {
event_type: eventType,
user_id: this.userId || this.deviceId,
device_id: this.deviceId,
session_id: this.sessionId,
time: Date.now(),
event_properties: eventProperties,
user_properties: this.userProperties,
platform: 'Chrome Extension',
app_version: '4.0.0'
};
try {
const response = await fetch('https://api2.amplitude.com/2/httpapi', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
api_key: AMPLITUDE_API_KEY,
events: [event]
})
});
if (!response.ok) {
console.warn('Amplitude tracking failed:', response.status);
}
} catch (error) {
console.warn('Amplitude tracking error:', error);
}
}
// Track authentication events
trackAuthEvent(eventType, additionalProperties = {}) {
this.trackEvent('Authentication Event', {
event_type: eventType,
timestamp: new Date().toISOString(),
...additionalProperties
});
}
}
const amplitudeTracker = new AmplitudeTracker();
window.amplitudeTracker = amplitudeTracker;- api2.amplitude.com
Amplitude HTTP API endpoint that receives the popup authentication analytics event.
What it can do
Permissions this extension asks for, as declared in version 4.1.4. 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 api.ytu.routeme.me
https://api.ytu.routeme.me/*
Read and change your data on routeme.me
https://routeme.me/*
Route all of your browsing through a server of its choosing
proxy
Store data in your browser
storage
Schedule its own background tasks
alarms
Act on the current tab, but only after you click the extension
activeTab