Stealth mode plugin for puppeteer-extra that applies various techniques to make detection of headless browsers harder.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advanced evasion techniques that modify browser fingerprinting vectors including media codecs, WebGL properties, and comprehensive user agent handling. These evasions target sophisticated detection methods that analyze browser capabilities and characteristics.
Comprehensive user agent management that fixes user agent strings, platform information, and user agent client hints.
// Evasion name: 'user-agent-override'
// Fixes: User agent string, Accept-Language header, navigator.platform, UA client hintsConfiguration Options:
interface UserAgentOptions {
/** Custom user agent string (default: auto-generated from browser) */
userAgent?: string;
/** Locale for Accept-Language header (default: 'en-US,en') */
locale?: string;
/** Whether to mask Linux as Windows (default: true) */
maskLinux?: boolean;
}This evasion:
Detection Methods Prevented:
// These detection methods will be fooled:
// 1. Headless Chrome detection
if (navigator.userAgent.includes('HeadlessChrome')) {
// Would detect headless mode
}
// 2. Platform inconsistency detection
if (navigator.platform === 'Linux' && navigator.userAgent.includes('Windows')) {
// Would detect user agent spoofing
}
// 3. Language header inconsistency
// Accept-Language header now matches navigator.languagesUsage Examples:
// Use default user agent override
const stealth = StealthPlugin({
enabledEvasions: new Set(['user-agent-override'])
});
// Custom user agent and locale
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const UserAgentOverride = require('puppeteer-extra-plugin-stealth/evasions/user-agent-override');
const customUA = UserAgentOverride({
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
locale: 'de-DE,de',
maskLinux: false
});
puppeteer.use(customUA);Fixes media codec detection to prevent fingerprinting through supported audio/video formats.
// Evasion name: 'media.codecs'
// Fixes: HTMLMediaElement.canPlayType() responses for realistic codec supportThis evasion:
video.canPlayType() and audio.canPlayType()Detection Method Prevented:
// This detection method will be fooled:
const video = document.createElement('video');
const codecs = ['video/mp4', 'video/webm', 'video/ogg'];
const support = codecs.map(codec => video.canPlayType(codec));
if (support.every(s => s === '')) {
// Would detect unusual lack of codec support
}Fixes WebGL vendor and renderer information to prevent graphics-based fingerprinting.
// Evasion name: 'webgl.vendor'
// Fixes: WebGL vendor and renderer strings for realistic GPU fingerprintingThis evasion:
WEBGL_debug_renderer_info extension responsesDetection Method Prevented:
// This detection method will be fooled:
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
if (debugInfo) {
const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
if (vendor.includes('SwiftShader') || renderer.includes('SwiftShader')) {
// Would detect software rendering indicating automation
}
}Usage Examples:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
// Enable fingerprinting evasions
const fingerprintStealth = StealthPlugin({
enabledEvasions: new Set([
'user-agent-override',
'media.codecs',
'webgl.vendor'
])
});
puppeteer.use(fingerprintStealth);
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Fingerprinting will now return realistic values
await page.evaluate(() => {
// User agent is clean
console.log(navigator.userAgent); // No "HeadlessChrome"
// Media codecs work normally
const video = document.createElement('video');
console.log(video.canPlayType('video/mp4')); // "probably" or "maybe"
// WebGL vendor is realistic
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
if (debugInfo) {
console.log(gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL)); // "Google Inc."
}
});// Minimal user agent override (keeps original user agent, just removes headless indicators)
const minimalUA = StealthPlugin({
enabledEvasions: new Set(['user-agent-override'])
});
// Custom user agent with specific locale
const UserAgentOverride = require('puppeteer-extra-plugin-stealth/evasions/user-agent-override');
const customUA = UserAgentOverride({
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
locale: 'en-GB,en',
maskLinux: false
});
// Don't mask Linux (keep original platform)
const linuxUA = UserAgentOverride({
maskLinux: false,
locale: 'en-US,en'
});These evasions work together to provide comprehensive fingerprinting protection:
// Full fingerprinting protection
const fullFingerprintProtection = StealthPlugin({
enabledEvasions: new Set([
'user-agent-override', // Clean user agent and headers
'media.codecs', // Realistic media support
'webgl.vendor', // Clean WebGL fingerprint
'navigator.languages', // Consistent language reporting
'navigator.plugins', // Realistic plugin list
'window.outerdimensions' // Proper window dimensions
])
});The user agent override evasion:
The media codecs evasion:
The WebGL vendor evasion:
These fingerprinting evasions:
Install with Tessl CLI
npx tessl i tessl/npm-puppeteer-extra-plugin-stealth