MCP Server Security · Screen Details API · window.getScreenDetails() · Multi-Monitor Fingerprinting · VPN Detection · Window Management · isInternal
MCP server Screen Details API security
The Screen Details API (window.getScreenDetails(), Chrome 100+) returns detailed physical information about every connected display: pixel dimensions, DPI, refresh rate, color gamut, isInternal (built-in laptop display?), and screen arrangement geometry. MCP tool output with window-management permission can fingerprint specific hardware configurations, detect VMs and VPNs via implausible display properties, infer professional workstation setups, and place popup windows on targeted monitors — all beyond what window.screen exposes.
Screen Details API surface
// Screen Details API — Chrome 100+, Edge 100+
// Requires 'window-management' (formerly 'window-placement') permission
// Permission prompt: "Allow [site] to manage windows on all your displays?"
const permission = await navigator.permissions.query({ name: 'window-management' });
// 'granted', 'denied', or 'prompt'
// Only available after permission grant
const screenDetails = await window.getScreenDetails();
// screenDetails.screens = array of ScreenDetailed objects, one per physical display
screenDetails.screens.forEach(screen => {
console.log({
width: screen.width, // physical pixel width
height: screen.height, // physical pixel height
availWidth: screen.availWidth, // minus taskbar
devicePixelRatio: screen.devicePixelRatio, // DPI scaling factor
colorDepth: screen.colorDepth,
colorSpace: screen.colorSpace, // 'srgb' | 'display-p3' (future: 'rec2020')
isInternal: screen.isInternal, // true = built-in laptop display
isPrimary: screen.isPrimary, // true = primary display
left: screen.left, // x-position in virtual screen coordinate system
top: screen.top, // y-position
orientation: screen.orientation.type // 'landscape-primary' etc.
// Some browsers also expose: refreshRate (Hz), label (display name)
});
});
// screenDetails.currentScreen = ScreenDetailed for the display with the active window
// screenDetails.addEventListener('screenschange', ...) — fires when displays added/removed
Permission surface: the window-management permission prompt describes the capability as "manage windows on all your displays" — users may grant it expecting benign window placement, not realizing it also exposes detailed display hardware metadata.
Attack 1 — high-entropy hardware fingerprint
Each physical display has a combination of width, height, devicePixelRatio, colorSpace, isInternal, and refresh rate that is highly specific. Two users with the same single external monitor model may share many values, but the combination of primary + secondary + laptop screen geometry is often unique to an individual workstation.
// Build a high-entropy fingerprint from screen configuration
async function buildScreenFingerprint() {
const sd = await window.getScreenDetails();
const screens = sd.screens.map(s => [
s.width, s.height,
s.devicePixelRatio,
s.colorSpace,
s.isInternal ? 1 : 0,
s.isPrimary ? 1 : 0,
s.left, s.top
].join(':'));
// e.g., "2560:1440:2:srgb:0:1:0:0|1920:1080:1:srgb:0:0:2560:180|2560:1600:2:display-p3:1:0:-2560:0"
// Three-monitor professional workstation: near-unique fingerprint
return screens.sort().join('|');
}
// Combined with navigator.hardwareConcurrency and deviceMemory
// this fingerprint persists across incognito sessions (hardware doesn't change)
Attack 2 — VM and VPN detection
Virtual machines typically expose screen dimensions that don't match standard physical hardware profiles. Remote Desktop (RDP) sessions report unusual DPI/resolution combinations. VPNs sometimes trigger changes in the display driver that affect reported properties. These anomalies allow detection of sandboxed, virtualized, or remoted environments.
// Heuristics for VM/remote environment detection
async function detectVirtualizedEnvironment() {
const sd = await window.getScreenDetails();
const primary = sd.screens.find(s => s.isPrimary);
const signals = {
// VMs often report exactly 1:1 pixel ratio
suspiciousPixelRatio: primary.devicePixelRatio === 1 &&
primary.width > 2560, // high-res but no HiDPI = VM
// Standard resolutions in VMs: exactly 1024x768, 1280x720, 1600x900
standardVmResolution: [
[1024, 768], [1280, 720], [1280, 800],
[1600, 900], [1920, 1080]
].some(([w, h]) => primary.width === w && primary.height === h &&
primary.devicePixelRatio === 1),
// No internal display = desktop machine or VM (no laptop)
noInternalDisplay: !sd.screens.some(s => s.isInternal),
// RDP: single display, no isInternal, srgb color space
rdpProfile: sd.screens.length === 1 &&
!primary.isInternal &&
primary.colorSpace === 'srgb' &&
primary.devicePixelRatio === 1
};
return Object.values(signals).filter(Boolean).length >= 2;
}
Attack 3 — targeted window placement on specific monitors
The window-management permission that unlocks Screen Details also enables window.open() with exact screen coordinates. A malicious MCP tool can open popups on a secondary display the user isn't watching, or precisely target the display running a screen recorder to ensure content appears in the recording.
// Open popup specifically on the secondary monitor (not the one user is watching)
async function openPopupOnSecondaryMonitor(url) {
const sd = await window.getScreenDetails();
const secondary = sd.screens.find(s => !s.isPrimary && !s.isInternal);
if (secondary) {
window.open(url,
'_blank',
`left=${secondary.left + 100},top=${secondary.top + 100},width=400,height=300`
);
// Popup appears on secondary screen — user may not notice
}
}
SkillAudit findings
Defense
| Defense | Effectiveness |
|---|---|
| Permissions-Policy: window-management=() | High — blocks getScreenDetails() entirely. Add to HTTP response headers for MCP tool rendering contexts. |
| Never grant 'window-management' permission | High — the permission prompt is the primary defense. Deny unless the tool explicitly requires multi-monitor window placement. |
| CSP frame-src/script-src | None — does not restrict JS API access. |
| Audit for window.getScreenDetails() calls | High — static analysis flag; few legitimate uses in MCP tool context. |
Related: Window Management API security · Screen Capture API security · Device Memory API security