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

window-frame-evasions.mddocs/

0

# Window and Frame Evasions

1

2

Evasion techniques that fix window dimension and iframe-related detection methods. These evasions address inconsistencies in window properties and iframe behavior that can reveal headless browser automation.

3

4

## Capabilities

5

6

### Window Outer Dimensions Evasion

7

8

Fixes missing `window.outerWidth` and `window.outerHeight` properties in headless mode.

9

10

```javascript { .api }

11

// Evasion name: 'window.outerdimensions'

12

// Fixes: window.outerWidth, window.outerHeight, and viewport consistency

13

```

14

15

This evasion:

16

- Sets realistic `window.outerWidth` and `window.outerHeight` values in headless mode

17

- Ensures outer dimensions are larger than inner dimensions (like real browsers)

18

- Automatically adjusts viewport to match window dimensions unless specified by user

19

- Prevents detection through missing or inconsistent window dimension properties

20

21

**Detection Method Prevented:**

22

```javascript

23

// This detection method will be fooled:

24

if (window.outerWidth === 0 || window.outerHeight === 0) {

25

// Would detect headless mode (missing outer dimensions)

26

} else if (window.outerWidth <= window.innerWidth) {

27

// Would detect unusual dimension relationship

28

} else {

29

// Assumes normal browser with proper window chrome

30

}

31

```

32

33

**Usage Examples:**

34

35

```javascript

36

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

37

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

38

39

// Enable window dimensions evasion

40

const windowStealth = StealthPlugin({

41

enabledEvasions: new Set(['window.outerdimensions'])

42

});

43

44

puppeteer.use(windowStealth);

45

46

const browser = await puppeteer.launch({ headless: true });

47

const page = await browser.newPage();

48

49

// Window dimensions will now be realistic

50

await page.evaluate(() => {

51

console.log('Inner:', window.innerWidth, 'x', window.innerHeight);

52

console.log('Outer:', window.outerWidth, 'x', window.outerHeight);

53

54

// Outer dimensions will be larger than inner (accounting for browser chrome)

55

console.log('Has window chrome:', window.outerWidth > window.innerWidth);

56

// Returns: true (like a real browser)

57

});

58

```

59

60

### Iframe Content Window Evasion

61

62

Fixes iframe detection issues, particularly with `srcdoc` powered iframes.

63

64

```javascript { .api }

65

// Evasion name: 'iframe.contentWindow'

66

// Fixes: iframe.contentWindow.chrome detection and related iframe issues

67

```

68

69

This evasion:

70

- Prevents detection through iframe content window properties

71

- Fixes Chrome object availability in iframe contexts

72

- Addresses Chromium bugs with `srcdoc` iframes

73

- Ensures consistent behavior across iframe boundaries

74

75

**Detection Method Prevented:**

76

```javascript

77

// This detection method will be fooled:

78

const iframe = document.createElement('iframe');

79

iframe.srcdoc = '<html><body></body></html>';

80

document.body.appendChild(iframe);

81

82

iframe.onload = () => {

83

if (iframe.contentWindow.chrome) {

84

// Assumes real Chrome browser

85

} else {

86

// Would detect headless/automation through missing Chrome object in iframe

87

}

88

};

89

```

90

91

**Implementation Details:**

92

93

The iframe content window evasion:

94

1. **Monitors Iframe Creation**: Watches for new iframe elements

95

2. **Patches Content Windows**: Applies stealth modifications to iframe content windows

96

3. **Handles srcdoc Iframes**: Specifically addresses Chromium bug with srcdoc-powered iframes

97

4. **Maintains Consistency**: Ensures Chrome objects are available across frame boundaries

98

5. **Prevents Leakage**: Stops detection methods that rely on iframe property differences

99

100

**Usage Examples:**

101

102

```javascript

103

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

104

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

105

106

// Enable iframe evasion along with Chrome API evasions

107

const iframeStealth = StealthPlugin({

108

enabledEvasions: new Set([

109

'iframe.contentWindow',

110

'chrome.runtime',

111

'chrome.app'

112

])

113

});

114

115

puppeteer.use(iframeStealth);

116

117

const browser = await puppeteer.launch();

118

const page = await browser.newPage();

119

120

// Test iframe behavior

121

await page.evaluate(() => {

122

const iframe = document.createElement('iframe');

123

iframe.srcdoc = `

124

<html>

125

<body>

126

<script>

127

// This will now work properly without detection

128

console.log('Chrome in iframe:', typeof chrome !== 'undefined');

129

console.log('Chrome runtime:', typeof chrome?.runtime !== 'undefined');

130

</script>

131

</body>

132

</html>

133

`;

134

135

document.body.appendChild(iframe);

136

137

return new Promise(resolve => {

138

iframe.onload = () => {

139

// iframe content window now has proper Chrome objects

140

resolve(typeof iframe.contentWindow.chrome !== 'undefined');

141

};

142

});

143

});

144

```

145

146

## Window Dimension Management

147

148

### Automatic Viewport Adjustment

149

150

The window outer dimensions evasion automatically adjusts the browser viewport to create realistic dimension relationships:

151

152

```javascript

153

// The evasion automatically calculates appropriate dimensions

154

// Inner dimensions: Set by user or browser defaults

155

// Outer dimensions: Inner + realistic browser chrome size

156

157

const chromeSize = 85; // Typical browser chrome height

158

const outerWidth = innerWidth + 16; // Small width addition for scrollbars

159

const outerHeight = innerHeight + chromeSize; // Browser chrome height

160

```

161

162

### Custom Viewport Handling

163

164

If you set a custom viewport, the evasion respects your settings:

165

166

```javascript

167

const browser = await puppeteer.launch();

168

const page = await browser.newPage();

169

170

// Set custom viewport - evasion will adjust outer dimensions accordingly

171

await page.setViewport({ width: 1366, height: 768 });

172

173

// Outer dimensions will be calculated based on this viewport

174

// outerWidth: ~1382, outerHeight: ~853

175

```

176

177

## Cross-Frame Consistency

178

179

Both window and iframe evasions ensure consistency across different execution contexts:

180

181

### Main Frame vs Iframe

182

183

```javascript

184

// Main frame and all iframes will have consistent Chrome object availability

185

await page.evaluate(() => {

186

// Main frame

187

console.log('Main chrome:', typeof chrome);

188

189

const iframe = document.createElement('iframe');

190

iframe.srcdoc = '<script>parent.postMessage(typeof chrome, "*")</script>';

191

192

window.addEventListener('message', (e) => {

193

console.log('Iframe chrome:', e.data);

194

// Both will show 'object' if Chrome evasions are enabled

195

});

196

197

document.body.appendChild(iframe);

198

});

199

```

200

201

### Multiple Windows

202

203

Window evasions apply to all windows opened from the page:

204

205

```javascript

206

await page.evaluate(() => {

207

const newWindow = window.open('about:blank');

208

209

// New window will also have proper outer dimensions

210

setTimeout(() => {

211

console.log('New window outer:', newWindow.outerWidth, newWindow.outerHeight);

212

console.log('New window chrome:', typeof newWindow.chrome);

213

newWindow.close();

214

}, 100);

215

});

216

```

217

218

## Browser Compatibility

219

220

Window and frame evasions are designed for:

221

- **Chrome/Chromium**: Primary target with specific bug fixes

222

- **Headless Mode**: Specifically addresses headless-mode limitations

223

- **Cross-Platform**: Works consistently across Windows, macOS, and Linux

224

- **Multiple Versions**: Handles different Chrome/Chromium version behaviors

225

226

## Advanced Usage Patterns

227

228

### Selective Window Evasions

229

230

```javascript

231

// Only fix window dimensions, not iframe behavior

232

const windowOnly = StealthPlugin({

233

enabledEvasions: new Set(['window.outerdimensions'])

234

});

235

236

// Only fix iframe behavior, keep original window dimensions

237

const iframeOnly = StealthPlugin({

238

enabledEvasions: new Set(['iframe.contentWindow', 'chrome.runtime'])

239

});

240

```

241

242

### Integration with Other Evasions

243

244

Window and frame evasions work best when combined with related evasions:

245

246

```javascript

247

// Comprehensive window/frame protection

248

const windowFrameStealth = StealthPlugin({

249

enabledEvasions: new Set([

250

'window.outerdimensions', // Fix window dimensions

251

'iframe.contentWindow', // Fix iframe behavior

252

'chrome.runtime', // Provide Chrome objects in iframes

253

'chrome.app', // Complete Chrome API simulation

254

'navigator.webdriver' // Remove automation indicators

255

])

256

});

257

```