Back to Blog
Fingerprint

Screen and Window Fingerprinting: How Display Properties Track You

How screen resolution, color depth, and window dimensions create unique fingerprint signals, and how to control display identity.

Introduction

Your browser's display configuration tells websites a lot about your device. Screen resolution, color depth, device pixel ratio, available screen area, and window dimensions are all accessible through standard JavaScript APIs. No permissions are needed. These values vary across devices and monitor configurations, making them useful components of a browser fingerprint. A 1920x1080 display at 1x DPI is different from a 2560x1600 display at 2x DPI, which is different from a 3840x2160 display at 1.5x. When combined with other signals, display properties contribute meaningful entropy to a tracking fingerprint. This article explains how screen and window fingerprinting works and how BotBrowser provides controlled, consistent display identity through its profile system.

Privacy Impact

Display properties have been part of fingerprinting since the earliest tracking scripts. The EFF's Panopticlick project reported that screen resolution alone provides about 4.8 bits of entropy, enough to distinguish roughly 28 groups. When combined with color depth, device pixel ratio, and available screen area (which reveals taskbar size and position), the combined display fingerprint can contribute over 8 bits of entropy.

The proliferation of high-DPI displays, ultrawide monitors, and multi-monitor setups has increased display diversity. Ten years ago, most desktop users had 1920x1080 screens. Today, common resolutions include 2560x1440, 3840x2160, 2560x1600 (MacBook), 2880x1800, and various ultrawide configurations. Mobile devices add even more variety with per-model resolutions and pixel ratios.

A particularly effective technique combines screen resolution with window dimensions. The difference between screen size and window size reveals information about the operating system's UI chrome: taskbar height, dock width, window decorations. These margins differ between Windows, macOS, and Linux, and between OS versions. A 40-pixel gap between screen.height and screen.availHeight suggests Windows with a bottom taskbar. A 25-pixel gap might indicate macOS with a hidden dock.

Technical Background

Screen Properties

The screen object provides display information:

  • screen.width / screen.height - The full screen resolution in CSS pixels.
  • screen.availWidth / screen.availHeight - The screen area available to browser windows (minus taskbars, docks, etc.).
  • screen.colorDepth - The color depth in bits per pixel. Almost universally 24 on modern systems.
  • screen.pixelDepth - Usually equal to colorDepth.

Window Properties

The window object exposes inner and outer dimensions:

  • window.innerWidth / window.innerHeight - The viewport dimensions, excluding browser chrome.
  • window.outerWidth / window.outerHeight - The total window dimensions, including browser chrome (toolbar, tabs, scrollbar).
  • window.screenX / window.screenY - The window's position on screen.

Device Pixel Ratio

  • window.devicePixelRatio - The ratio between physical pixels and CSS pixels. A value of 2 means each CSS pixel maps to a 2x2 grid of physical pixels (common on Retina/HiDPI displays).

CSS Media Queries

Media queries provide access to display characteristics from CSS:

@media (min-resolution: 2dppx) { /* HiDPI styles */ }
@media (color-gamut: p3) { /* Wide color gamut display */ }
@media (prefers-color-scheme: dark) { /* Dark mode */ }

JavaScript can query these via window.matchMedia(), providing another avenue to read display properties.

Why These Values Vary

Display properties depend on several factors:

  • Monitor hardware. Physical resolution, size, and capabilities determine the base values.
  • OS display settings. Scaling settings (100%, 125%, 150%, 200%) affect the relationship between physical pixels and CSS pixels.
  • Multi-monitor configuration. Multiple displays with different resolutions and scaling create unique configurations.
  • Browser window state. Maximized, windowed, or full-screen mode affects inner/outer dimensions.
  • Operating system chrome. Taskbar/dock size and position affect available screen area.

The combination of these factors creates a high-entropy signal. A user with a 3440x1440 ultrawide monitor at 1.25x scaling, with a 48-pixel Windows taskbar, has a very distinctive display fingerprint.

Common Protection Approaches and Their Limitations

Browser extensions that modify screen properties typically override JavaScript getters on the screen and window objects. This has several problems. CSS media queries can read the real values independently of JavaScript. The visualViewport API provides another reading of viewport dimensions. The overridden getters can be detected through prototype inspection and timing analysis.

Using a common resolution (setting your display to 1920x1080) reduces uniqueness but does not address window dimensions, available screen area, or device pixel ratio. It also sacrifices display quality on HiDPI monitors.

Randomizing display values creates physically impossible configurations. A screen width of 1923 pixels does not correspond to any real monitor. A device pixel ratio of 1.37 does not correspond to any real display scaling setting. These values are detectable as synthetic.

Running in a virtual machine with controlled display settings helps but introduces VM-specific signals. VM display drivers often report specific capability sets and parameter combinations that identify the virtualization platform.

Headless browser modes present their own challenge. Default headless Chromium uses a 800x600 viewport with a device pixel ratio of 1, which is a distinctive fingerprint in itself because very few real users browse at that configuration.

BotBrowser's Engine-Level Approach

BotBrowser controls all display-related properties at the Chromium engine level through its profile system.

Complete Display Profile

When a fingerprint profile is loaded, BotBrowser configures:

  • Screen dimensions (screen.width, screen.height, screen.availWidth, screen.availHeight) to match the profiled device.
  • Window dimensions (window.innerWidth, window.innerHeight, window.outerWidth, window.outerHeight) with realistic OS chrome margins derived from the profile.
  • Device pixel ratio matching the profiled display configuration.
  • Color depth and pixel depth consistent with the profiled device.

CSS Media Query Alignment

BotBrowser ensures that CSS media queries return values consistent with the JavaScript properties. matchMedia('(min-width: 1920px)') agrees with screen.width. matchMedia('(resolution: 2dppx)') agrees with devicePixelRatio. There is no gap between CSS-based and JavaScript-based display queries.

OS Chrome Simulation

The difference between outer and inner window dimensions, and between screen size and available screen area, is derived from the profile's target operating system. A Windows profile includes Windows-typical borders and taskbar dimensions. A macOS profile includes macOS-typical menu bar and window decoration sizes.

Headless Mode Control

In headless mode, BotBrowser applies the profile's display configuration instead of the default 800x600. This means headless sessions have display properties indistinguishable from headed sessions with the same profile.

Configuration and Usage

Basic Display Protection

chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)"

Window and Screen Configuration

# Use profile's window settings (default for headless)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-window=profile \
       --bot-config-screen=profile

# Specify exact window size
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-window=1920x1080

# Specify exact screen size
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-screen=2560x1440

# Full JSON customization
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-window='{"innerWidth":1920,"innerHeight":1080,"devicePixelRatio":2}'

# Use real system dimensions (default for desktop headful)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-window=real \
       --bot-config-screen=real

Color Scheme Control

chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-color-scheme=light

Playwright Integration

const { chromium } = require('playwright');

const browser = await chromium.launch({
  executablePath: '/path/to/botbrowser/chrome',
  args: [
    '--bot-profile=/path/to/profile.enc',
    '--bot-config-window=profile',
    '--bot-config-screen=profile'
  ]
});

const page = await browser.newPage();
await page.goto('https://example.com');

const screenInfo = await page.evaluate(() => ({
  screenWidth: screen.width,
  screenHeight: screen.height,
  innerWidth: window.innerWidth,
  innerHeight: window.innerHeight,
  devicePixelRatio: window.devicePixelRatio
}));
console.log(screenInfo);

Puppeteer Integration

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({
  executablePath: '/path/to/botbrowser/chrome',
  defaultViewport: null,  // Important: use profile dimensions
  args: [
    '--bot-profile=/path/to/profile.enc',
    '--bot-config-window=profile',
    '--bot-config-screen=profile'
  ]
});

const page = await browser.newPage();
await page.goto('https://example.com');

Note the defaultViewport: null setting in Puppeteer. Without this, Puppeteer overrides the viewport to its own defaults, which would conflict with the profile's display settings.

Verification

Screen property check. Query screen.width, screen.height, screen.availWidth, screen.availHeight, and screen.colorDepth. All values should match the profile's target device.

Window dimension check. Query window.innerWidth, window.innerHeight, window.outerWidth, window.outerHeight. The margins between inner and outer should be realistic for the profiled OS.

DPI check. Verify that window.devicePixelRatio matches the profile. Check that CSS media queries for resolution agree.

Media query consistency. Use window.matchMedia() to query display-related media features and confirm they align with the JavaScript property values.

Best Practices

  • Use defaultViewport: null in Puppeteer. This prevents Puppeteer from overriding the profile's display settings.
  • Use --bot-config-window=profile in headless mode. This applies the profile's window dimensions instead of the default headless viewport.
  • Match display profile to use case. If your proxy IP locates to a region where mobile browsing is common, consider using a mobile profile with appropriate screen dimensions.
  • Do not set unrealistic resolutions. Values like 1920x1080, 2560x1440, and 1440x900 are common. Values like 1919x1079 are not.
  • Account for device pixel ratio. High-DPI profiles report higher physical resolutions with DPR of 2 or 3. Ensure your profile's DPR is consistent with the reported screen size.

FAQ

Q: Does BotBrowser handle multi-monitor detection? A: BotBrowser profiles describe a single display configuration. The profile's screen values represent the primary monitor as reported to web content. Multi-monitor window movement tracking is not exposed to web pages by default.

Q: What happens if I resize the browser window with a profile loaded? A: window.innerWidth and window.innerHeight update to reflect the actual window size (in headed mode with --bot-config-window=real). In headless mode or with --bot-config-window=profile, the values remain controlled by the profile.

Q: Does the color scheme setting affect rendering? A: Yes. --bot-config-color-scheme=dark causes prefers-color-scheme: dark to be true in CSS media queries and matchMedia(). Websites that implement dark mode will render accordingly.

Q: Is the screen fingerprint the same in headless and headed mode? A: When using --bot-config-window=profile and --bot-config-screen=profile, yes. Without these flags, headed mode defaults to real window/screen dimensions while headless uses the profile.

Q: Does BotBrowser support ultrawide or non-standard aspect ratios? A: BotBrowser profiles can include any screen configuration that exists on real hardware. If a profile was captured from a device with an ultrawide monitor, those dimensions are available.

Q: How does the visualViewport API interact with BotBrowser's protection? A: The visualViewport API returns values consistent with the controlled window dimensions. There is no gap between window.innerWidth and visualViewport.width.

Summary

Screen and window properties are among the most commonly collected fingerprint signals because they require no permissions and vary widely across hardware configurations. BotBrowser controls all display-related values at the engine level, including screen dimensions, window dimensions, device pixel ratio, color depth, and CSS media queries. By loading a complete fingerprint profile, all display signals align with a real device configuration, and headless sessions produce the same display fingerprint as headed sessions.

For related topics, see What is Browser Fingerprinting, CSS Signal Consistency, Navigator Property Protection, and Deterministic Browser Behavior.

#screen#window#fingerprinting#display#privacy