(async function runLeakTest() {
// Get public IP from external service
async function getPublicIP() {
try {
const res = await fetch('https://api.ipify.org?format=json');
const data = await res.json();
return data.ip;
} catch (e) {
return 'Error';
}
}
// Collect WebRTC candidate IPs
async function getWebRTCIPs() {
return new Promise((resolve) => {
const ips = new Set();
const pc = new RTCPeerConnection({ iceServers: [] });
pc.createDataChannel('');
pc.createOffer().then((offer) => pc.setLocalDescription(offer));
pc.onicecandidate = (event) => {
if (!event || !event.candidate) {
pc.close();
resolve(Array.from(ips));
return;
}
const match = event.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3})/);
if (match) ips.add(match[1]);
};
});
}
// Collect browser and device profiling info
async function getDeviceProfile() {
const profile = {
userAgent: navigator.userAgent,
language: navigator.language,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
platform: navigator.platform,
doNotTrack: navigator.doNotTrack || 'unspecified',
screenResolution: `${window.screen.width}x${window.screen.height}`,
colorDepth: `${window.screen.colorDepth}`,
touchSupport: 'ontouchstart' in window,
pluginsCount: navigator.plugins ? navigator.plugins.length : 0,
hardwareConcurrency: navigator.hardwareConcurrency || 'unknown',
deviceMemory: navigator.deviceMemory || 'unknown',
};
// Try to get battery info (may be blocked)
try {
const battery = await navigator.getBattery?.();
if (battery) {
profile.batteryLevel = `${Math.round(battery.level * 100)}%`;
profile.batteryCharging = battery.charging;
}
} catch {
profile.batteryLevel = 'unavailable';
}
return profile;
}
// Run the leak test
const timestamp = new Date().toISOString();
const publicIP = await getPublicIP();
const webrtcIPs = await getWebRTCIPs();
const profile = await getDeviceProfile();
const leakDetected = webrtcIPs.some(ip => ip !== publicIP);
const csvHeaders = [
'Timestamp',
'Public IP',
'WebRTC IPs',
'Leak Detected',
'User Agent',
'Language',
'Timezone',
'Platform',
'Do Not Track',
'Screen Resolution',
'Color Depth',
'Touch Support',
'Plugins Count',
'CPU Cores',
'Memory (GB)',
'Battery Level',
'Battery Charging'
];
const csvRow = [
timestamp,
publicIP,
`"${webrtcIPs.join(' | ')}"`,
leakDetected ? 'Yes' : 'No',
`"${profile.userAgent}"`,
profile.language,
profile.timezone,
profile.platform,
profile.doNotTrack,
profile.screenResolution,
profile.colorDepth,
profile.touchSupport,
profile.pluginsCount,
profile.hardwareConcurrency,
profile.deviceMemory,
profile.batteryLevel || 'N/A',
profile.batteryCharging ?? 'N/A'
];
const csvOutput = csvHeaders.join(',') + '\n' + csvRow.join(',');
console.log('IP/DNS Leak & Profiling Test Complete\n');
console.log(csvOutput);
})();