or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

chrome-evasions.mdcore-plugin.mdfingerprinting-evasions.mdindex.mdmisc-evasions.mdnavigator-evasions.mdwindow-frame-evasions.md

navigator-evasions.mddocs/

0

# Navigator Evasions

1

2

Evasion techniques that modify navigator properties to hide headless browser indicators. These techniques fix various navigator object properties that can reveal automation and make the browser appear more like a regular user's browser.

3

4

## Capabilities

5

6

### Navigator WebDriver Evasion

7

8

Removes or fixes the `navigator.webdriver` property that explicitly indicates automation.

9

10

```javascript { .api }

11

// Evasion name: 'navigator.webdriver'

12

// Fixes: navigator.webdriver property detection

13

// Launch args: Adds --disable-blink-features=AutomationControlled

14

```

15

16

This evasion:

17

- Deletes the `navigator.webdriver` property in older Chrome versions

18

- Handles different Chrome version behaviors (pre/post Chrome 88 and 89)

19

- Adds `--disable-blink-features=AutomationControlled` launch argument

20

- Prevents the most common automation detection method

21

22

**Detection Method Prevented:**

23

```javascript

24

// This detection method will be fooled:

25

if (navigator.webdriver) {

26

// Detects automation - webdriver property exists

27

} else {

28

// Assumes regular browser

29

}

30

```

31

32

### Navigator Languages Evasion

33

34

Fixes the `navigator.languages` array to match the Accept-Language header.

35

36

```javascript { .api }

37

// Evasion name: 'navigator.languages'

38

// Fixes: Inconsistency between navigator.languages and Accept-Language header

39

```

40

41

This evasion:

42

- Ensures `navigator.languages` matches the Accept-Language header

43

- Provides consistent language reporting across different browser APIs

44

- Prevents detection through language inconsistencies

45

46

**Detection Method Prevented:**

47

```javascript

48

// This detection method will be fooled:

49

const languages = navigator.languages;

50

const acceptLanguage = /* from HTTP headers */;

51

if (languages.join(',') !== acceptLanguage) {

52

// Detects inconsistency indicating automation

53

}

54

```

55

56

### Navigator Hardware Concurrency Evasion

57

58

Fixes hardware concurrency reporting to match typical user systems.

59

60

```javascript { .api }

61

// Evasion name: 'navigator.hardwareConcurrency'

62

// Fixes: navigator.hardwareConcurrency to report realistic CPU core count

63

```

64

65

This evasion:

66

- Reports a realistic number of CPU cores

67

- Prevents detection through unusual hardware concurrency values

68

- Matches typical desktop/laptop configurations

69

70

**Detection Method Prevented:**

71

```javascript

72

// This detection method will be fooled:

73

if (navigator.hardwareConcurrency === 1 || navigator.hardwareConcurrency > 16) {

74

// Detects unusual hardware suggesting automation environment

75

}

76

```

77

78

### Navigator Permissions Evasion

79

80

Fixes permission API behavior, particularly for notifications.

81

82

```javascript { .api }

83

// Evasion name: 'navigator.permissions'

84

// Fixes: Notification.permission and navigator.permissions.query() behavior

85

```

86

87

This evasion:

88

- Fixes `Notification.permission` behavior in headless mode

89

- Ensures `navigator.permissions.query()` returns expected results

90

- Addresses Chromium bug with notification permissions in headless mode

91

92

**Detection Method Prevented:**

93

```javascript

94

// This detection method will be fooled:

95

navigator.permissions.query({name: 'notifications'}).then(result => {

96

if (result.state !== Notification.permission) {

97

// Detects permission API inconsistency

98

}

99

});

100

```

101

102

### Navigator Plugins Evasion

103

104

Mocks browser plugins to simulate a regular browser environment.

105

106

```javascript { .api }

107

// Evasion name: 'navigator.plugins'

108

// Fixes: Empty navigator.plugins array in headless mode

109

```

110

111

This evasion:

112

- Creates realistic `navigator.plugins` array with common plugins

113

- Includes typical plugins like Chrome PDF Viewer, Flash, etc.

114

- Provides proper plugin objects with realistic properties

115

- Implements plugin detection methods used by websites

116

117

**Detection Method Prevented:**

118

```javascript

119

// This detection method will be fooled:

120

if (navigator.plugins.length === 0) {

121

// Detects headless browser with no plugins

122

} else {

123

// Assumes regular browser with plugins

124

}

125

```

126

127

### Navigator Vendor Evasion

128

129

Allows customization of the `navigator.vendor` property which is fixed in Puppeteer by default.

130

131

```javascript { .api }

132

/**

133

* Navigator vendor evasion plugin

134

* @param opts - Configuration options

135

* @param opts.vendor - The vendor string to use (default: 'Google Inc.')

136

* @returns Plugin instance

137

*/

138

function NavigatorVendorPlugin(opts?: {

139

vendor?: string;

140

}): Plugin;

141

142

// Evasion name: 'navigator.vendor'

143

// Fixes: Fixed navigator.vendor property in headless mode

144

// Configuration: Accepts custom vendor string

145

```

146

147

This evasion:

148

- Overrides the fixed `navigator.vendor` property

149

- Allows setting custom vendor string (default: 'Google Inc.')

150

- Uses stealth utilities to replace the property undetectably

151

- Can be used to mimic different browser vendors

152

153

**Configuration Options:**

154

```javascript

155

// Use default vendor (Google Inc.)

156

const vendorPlugin = NavigatorVendorPlugin();

157

158

// Use custom vendor

159

const appleVendor = NavigatorVendorPlugin({

160

vendor: 'Apple Computer, Inc.'

161

});

162

```

163

164

**Detection Method Prevented:**

165

```javascript

166

// This detection method will be fooled:

167

if (navigator.vendor === 'Google Inc.' && /* other headless indicators */) {

168

// Might detect specific headless patterns

169

} else {

170

// Custom vendor helps avoid detection patterns

171

}

172

```

173

174

**Usage Examples:**

175

176

```javascript

177

const puppeteer = require('puppeteer-extra');

178

const StealthPlugin = require('puppeteer-extra-plugin-stealth');

179

180

// Enable only navigator-related evasions

181

const navigatorStealth = StealthPlugin({

182

enabledEvasions: new Set([

183

'navigator.webdriver',

184

'navigator.languages',

185

'navigator.hardwareConcurrency',

186

'navigator.permissions',

187

'navigator.plugins',

188

'navigator.vendor'

189

])

190

});

191

192

puppeteer.use(navigatorStealth);

193

194

const browser = await puppeteer.launch();

195

const page = await browser.newPage();

196

197

// Navigator properties will now appear normal

198

await page.evaluate(() => {

199

console.log(navigator.webdriver); // undefined (not true)

200

console.log(navigator.languages); // ['en-US', 'en']

201

console.log(navigator.hardwareConcurrency); // 4 (realistic number)

202

console.log(navigator.plugins.length); // > 0 (has plugins)

203

console.log(navigator.vendor); // 'Google Inc.' (customizable)

204

205

// Permissions work normally

206

return navigator.permissions.query({name: 'notifications'});

207

});

208

```

209

210

## Configuration Interaction

211

212

Navigator evasions work together with other plugin components:

213

214

### User Agent Override Integration

215

216

The `navigator.languages` evasion coordinates with `user-agent-override` to ensure:

217

- Accept-Language header matches navigator.languages

218

- User agent string is consistent with reported languages

219

- Platform information aligns across different APIs

220

221

### Launch Arguments

222

223

The `navigator.webdriver` evasion adds launch arguments:

224

- `--disable-blink-features=AutomationControlled`

225

- May add Chrome policy warning (can be disabled with system policies)

226

227

## Implementation Details

228

229

Each navigator evasion:

230

231

1. **Runtime Injection**: Uses `page.evaluateOnNewDocument()` for immediate execution

232

2. **Property Modification**: Uses stealth utilities to modify properties undetectably

233

3. **Cross-Frame Support**: Works across iframes and new windows

234

4. **Version Compatibility**: Handles different Chrome/Chromium versions appropriately

235

5. **Realistic Data**: Provides believable values that match real user environments

236

237

## Browser Compatibility

238

239

Navigator evasions are designed for:

240

- **Chrome/Chromium**: Primary target with version-specific handling

241

- **Puppeteer**: Full compatibility with all Puppeteer versions

242

- **Playwright**: Compatible with playwright-extra

243

- **Cross-Platform**: Works on Windows, macOS, and Linux

244

245

## Advanced Usage

246

247

### Custom Plugin Configuration

248

249

```javascript

250

// Enable specific navigator evasions with custom values

251

const customNavigator = StealthPlugin({

252

enabledEvasions: new Set(['navigator.webdriver', 'navigator.plugins', 'navigator.vendor'])

253

});

254

255

// For individual evasion plugins with custom options:

256

const customVendor = require('puppeteer-extra-plugin-stealth/evasions/navigator.vendor');

257

puppeteer.use(customVendor({ vendor: 'Apple Computer, Inc.' }));

258

```

259

260

### Debugging Navigator Properties

261

262

```javascript

263

// Check which navigator properties are being modified

264

await page.evaluate(() => {

265

const props = [

266

'webdriver', 'languages', 'hardwareConcurrency',

267

'permissions', 'plugins', 'vendor'

268

];

269

270

return props.map(prop => ({

271

property: prop,

272

value: navigator[prop],

273

type: typeof navigator[prop]

274

}));

275

});

276

```