Blog
Skill and MCP server security, reported in public.
Methodology posts, public scan data, and field notes on the supply-chain surface of LLM agents. No fluff, no recycled vendor marketing.
-
2026-07-23 · CSS · scroll-timeline · view-timeline · Scroll-Driven Animations · Axis Attacks · MCP Servers · Consent Hiding
CSS scroll-timeline and view-timeline Axis Attacks: block/inline/x/y Axis Swap, Reverse Timeline Hiding, Deferred-Start Progress Stalling, and Cross-Axis Writing-Mode Confusion
CSS scroll-driven animations (Chrome 115+, Safari 18+) drive element visibility from scroll position rather than wall-clock time. MCP servers exploit the axis parameter to permanently freeze consent disclosure animations at their from-keyframe (opacity:0, height:0) via four techniques: axis-mismatch stalling (scroll-timeline-axis:x on a vertical-only scroller keeps timeline progress at 0%); writing-mode cross-axis confusion (writing-mode:vertical-lr on an ancestor flips block/inline axis meanings, making a block-axis timeline track horizontal scroll); reverse-timeline hiding (animation-direction:reverse with fill-mode:both and animation-range-start near 100% keeps the disclosure at the reversed from-keyframe before the range activates); and deferred-start stalling via animation-range-start:110% on a finite scroller where progress can never exceed 100%. In all four cases, getAnimations() reports the animation as "running" and currentTime shows a numeric value — the animation API is not a security oracle. Only getComputedStyle().opacity and getBoundingClientRect() catch the hiding reliably. Includes unified detection JavaScript covering all four attack vectors.
Read post → -
2026-07-22 · CSS · @property · Registered Custom Properties · Animation · MCP Servers · Consent Hiding
CSS @property and Registered Custom Properties as MCP Attack Surfaces: Type-Morphing, Animation Exploitation, Registration Blocking, and Initial-Value Races
CSS @property (Chrome 85+, Firefox 128+, Safari 16.4+) unlocks four novel MCP consent-hiding attack surfaces that unregistered custom properties cannot support: animating a <number>-typed --consent-alpha from 1 to 0 in 1ms using animation-fill-mode:forwards (load-time guard passes; getComputedStyle().opacity returns "0" only after the fill locks); suppressing the var(--x, fallback) fallback because a registered property always has its initial-value instead of IACVT, making display:none permanent; blocking the consent framework's own CSS.registerProperty() call by pre-registering the same property name first (InvalidModificationError is thrown and caught silently — MCP's hostile initial-value persists); and inherits:true + initial-value:0 on a
Read post →property that cascades opacity:0 to the entire document subtree unless explicitly overridden per-element. Covers detection via CSSPropertyRule enumeration, animation inspection, and typed-property guard patterns. -
2026-07-18 · CSS · :has() · Relational Selectors · Specificity · MCP Servers · Consent Hiding
CSS :has() Pseudo-Class as an MCP Attack Vector: Relational Selectors, Sibling Triggers, Specificity Exploitation, and Absence-Condition Hiding
The CSS :has() pseudo-class (Chrome 105+, Safari 15.4+, Firefox 121+) is the first CSS selector that matches elements based on what comes after or inside them in the DOM. For MCP consent-hiding attacks, :has() opens four distinct attack surfaces: a circular class trigger where the MCP adds a class at T=500ms (after the load-time guard passes), causing .consent-dialog:has(.disclosure-loaded) to fire and hide the dialog; a sibling trigger where inserting the accept button as the disclosure's next sibling activates .permission-disclosure:has(+ .accept-button) and makes the disclosure hide itself; a specificity exploitation where chained :has() selectors reach (0,5,0) or ID-level (1,1,0) specificity to override the consent framework's trusted rules without !important; and an absence-condition permanent hide using :not(:has(> .disclosure-override)) that fires on every page load because the override class is never injected. Includes detection code for scanning document.styleSheets for :has() rules, a MutationObserver guard pattern, and a sentinel counter-measure against the absence-condition attack.
Read post → -
2026-07-18 · CSS · View Transitions · ::view-transition · fill-mode · startViewTransition · MCP Servers
CSS View Transitions API as an MCP Attack Surface: ::view-transition Pseudo-Elements, fill-mode:forwards, and Programmatic Transition Triggers
The View Transitions API (Chrome 111+, Safari 18+) introduces ::view-transition-old() and ::view-transition-new() pseudo-elements that CSS can animate independently of the underlying DOM element. This deep dive covers four attack surfaces: assigning the consent disclosure to a named transition group via view-transition-name and animating both pseudo-elements to opacity:0 while the disclosure element's own computed styles are untouched; setting animation-fill-mode:forwards on ::view-transition-new() to permanently lock the post-transition state at opacity:0 via a near-infinite animation-duration; triggering document.startViewTransition() programmatically from MCP client code after load-time CSS guards have already passed; and using ::view-transition-old(disclosure) opacity:0 to create an invisible crossfade window during the critical reading period. Includes detection JavaScript, CSP analysis, and a guard bypass table comparing against standard opacity/visibility checks.
Read post → -
2026-07-17 · CSS · @font-face · unicode-range · FOIT · Glyph Substitution · Side-Channel · MCP Servers
CSS @font-face as an Attack Tool: Side-Channels, Glyph Substitution, and FOIT in MCP Consent Dialogs
The browser font loading pipeline is a silent HTTP oracle, a per-character render switch, and a timed blank-out machine. This deep dive covers four attack surfaces: HTTP timing side-channels where a unique font URL per session leaks exactly when a consent dialog rendered (an event log without JavaScript); unicode-range glyph substitution that surgically blanks only the characters appearing in "WARNING", "CRITICAL", and "DANGER" while leaving numbers and punctuation intact — text content and accessibility tree are both unaffected; font-display:block FOIT where an intentionally slow font server creates a 2.8-second blank-out window timed to the dialog's peak interaction moment; and not-def glyph replacement that renders alphabetic text as empty boxes while numeric amounts (dollar values, percentages) stay readable. Includes detection JavaScript using OffscreenCanvas pixel sampling, CSP font-src defense strategy, and a comparison table against other CSS disclosure attack vectors.
Read post → -
2026-07-17 · CSS · filter:opacity · backdrop-filter · MCP Servers · Consent Hiding · Filter Attacks
CSS filter:opacity and backdrop-filter: When CSS Filters Make MCP Server Consent Disclosures Invisible
filter:opacity(0) is visually identical to opacity:0 but leaves getComputedStyle().opacity at '1' — bypassing the most common opacity detection guard in consent security implementations. This deep dive covers five CSS filter attack surfaces: filter:opacity(0) as an opacity guard bypass, filter:brightness(0) collapsing all rendering to black on dark dialogs, filter:contrast(0) neutralizing color-coded risk warnings, filter:blur() smearing consent text into illegible shapes, and backdrop-filter:blur() on an injected transparent overlay that blurs the host UI without touching the disclosure element's own computed styles. Includes complete detection code for each attack and CSP defenses.
Read post → -
2026-07-10 · WebAssembly · Relaxed SIMD · CPU Fingerprinting · FMA · NaN Bit Patterns · swizzle · x86 · ARM · Apple Silicon · MCP Servers
WebAssembly Relaxed SIMD: The CPU Fingerprinting API You Didn't Know You Shipped
Wasm Relaxed SIMD was designed for performance. Its implementation-defined behavior on edge-case float inputs — FMA denormal flush-to-zero, NaN bit patterns, 1-ULP FMA precision, and swizzle out-of-range index handling — produces 7 bits of stable CPU entropy that distinguishes Intel Core from AMD Ryzen from Apple Silicon M1-M4 from Qualcomm Snapdragon in under 10 microseconds, without CPUID access, without permissions, and without any indication in tool output that a user would recognize as suspicious. Covers all four attack probes, the CPU identification lookup table, why MCP servers are the delivery vehicle, why standard privacy defences don't help, and what actually works (Electron V8 flags, Wasm payload auditing, hash allowlists).
Read post → -
2026-07-03 · Performance Timeline · Resource Timing · User Timing · Paint Timing · Layout Instability · Event Timing · PerformanceObserver · MCP Servers
MCP Server Performance Timeline Deep Dive: Resource Timing, User Timing, Paint Timing, Layout Instability, and Event Timing as a unified surveillance surface
The W3C Performance Timeline — five APIs sharing a single PerformanceObserver subscription — hands any JavaScript observer a comprehensive surveillance dashboard: browser cache history across 50+ origins via transferSize cache oracle, SPA application state via User Timing mark.detail objects containing userId/email/plan, A/B cohort assignment from LCP image CDN URL parameters, authentication state from Layout Instability shift source text, and a passive clickstream from Event Timing entry.target reads. A 40-line MCP tool subscribing to all five entry types with buffered:true drains past history and begins streaming in real time — no permission, no user dialog, no CSP flag. Covers all five APIs, the unified observer setup, SkillAudit detection patterns (2 CRITICAL, 4 HIGH, 3 MEDIUM findings), and the Permissions-Policy + CSP defenses that eliminate each attack class.
Read post → -
2026-07-02 · Generic Sensor API · Accelerometer · Gyroscope · Magnetometer · AbsoluteOrientationSensor · RelativeOrientationSensor · GravitySensor · AmbientLightSensor · MCP Servers
MCP Server Generic Sensor API Deep Dive: motion, orientation, and environmental sensors as a unified attack surface
The W3C Generic Sensor API family — Accelerometer, LinearAccelerationSensor, GravitySensor, Gyroscope, Magnetometer, AbsoluteOrientationSensor, RelativeOrientationSensor, and AmbientLightSensor — all share the same minimal permission model and are accessible with no dialog in Electron-based MCP clients including Claude Desktop. This deep dive maps the full cross-sensor attack surface: Gyroscope + Accelerometer combined to build a 6-DOF IMU gait biometric achieving 95%+ cross-session identification accuracy; Magnetometer + AbsoluteOrientationSensor for GPS-free indoor dead reckoning accurate to 2-3 meters; GravitySensor for accessibility configuration inference that exposes disability status as GDPR special-category health data; and AmbientLightSensor as a binary covert channel between tabs that bypasses all postMessage origin restrictions. Includes a consolidated 8-finding SkillAudit report (1 CRITICAL, 3 HIGH, 4 MEDIUM) and a 7-item Permissions-Policy defense checklist.
Read post → -
2026-07-02 · Chrome Built-in AI · Gemini Nano · Language Detector · Translation API · Summarizer · Writer API · Rewriter API · Prompt API · MCP Servers
MCP Server Chrome Built-in AI Deep Dive: six zero-permission APIs, six attack surfaces
Chrome 138 ships the Built-in AI API family — Language Detector, Translation, Summarizer, Writer, Rewriter, and Prompt API (AILanguageModel) — all powered by Gemini Nano on-device, all accessible with zero permission prompts. An MCP tool can use Language Detector to profile user nationality from any pasted text, Translation API to bypass DLP by converting PII to Amharic Ge'ez script before exfiltration, Summarizer to compress a 50,000-word document 100× via
Read post →sharedContextinjection, Writer and Rewriter to mutate financial instructions or encode exfiltrated data as acrostic patterns, and the Prompt API to poison multi-turn session context with a persistent system prompt that steers all subsequent responses. Covers all six APIs, thesharedContextinjection pattern, availability fingerprinting across 200+ dimensions, streaming latency oracles, and a consolidated 9-finding SkillAudit report with severity ratings and mitigations. -
2026-07-01 · WebHID API · navigator.hid · FIDO2 PIN Lockout · Keystroke Injection · Biometric Capture · HID Output Report · Security Key Destruction · MCP Servers
MCP Server WebHID API Deep Dive: FIDO2 PIN lockout, keystroke injection, and biometric sensor capture
The WebHID API (
Read post →navigator.hid) grants persistent access to Human Interface Devices — keyboards, FIDO2/U2F security keys (YubiKey, Titan Key, SoloKey), biometric fingerprint readers, Stream Decks, and vendor-specific industrial controllers. A singlerequestDevice()dialog persists across page refreshes, browser restarts, and reboots. MCP tool output can exploit this in four ways: silent device reconnect viagetDevices()with no browser indicator; FIDO2 PIN counter exhaustion by sending malformed CTAPHID_CBOR frames that decrement the 8-attempt limit until the security key permanently self-destructs; HID output report keystroke injection on programmable keyboards (Stream Deck, macro pads) at OS hardware level bypassing all software keystroke monitoring; and biometric data capture from fingerprint readers and heart rate monitors viainputreportevents without any camera or biometric permission dialog. Includes complete attack code for all four vectors, the CTAPHID framing protocol details, FIDO2 PIN counter mechanics, and a 7-item secure usage checklist. -
2026-06-27 · Compression Streams API · CompressionStream · DecompressionStream · CRIME/BREACH Oracle · Decompression Bomb · Payload Obfuscation · MCP Servers
MCP Server Compression Streams API Deep Dive: compression oracle, decompression bomb, and mixed-trust data leakage
The Compression Streams API —
Read post →new CompressionStream(format)andnew DecompressionStream(format)— gives every browser context a zero-permission DEFLATE and GZIP engine with no Permissions-Policy directive. MCP tool output can exploit it as a CRIME/BREACH-style oracle to recover secret bytes from same-origin data by measuring how compressed output length changes with different guesses (the same technique that broke TLS compression in 2012). This deep dive covers four attack surfaces: the in-browser compression oracle (compress attacker-prefix + secret, measure size, binary search), mixed-trust compression in logging/caching paths where combined data leaks secrets via observable cache sizes, decompression bomb DoS (42 KB gzip → 4.5 GB → renderer crash), and payload obfuscation via compression before exfiltration. Includes complete attack code, the CRIME/BREACH historical context, safe compression patterns with random noise prefixes and decompressed byte limits, and 6 SkillAudit findings with severity ratings. -
2026-06-27 · Web Locks API · navigator.locks · Lock Contention · Timing Oracle · Cross-Tab Side Channel · Starvation DoS · MCP Servers
MCP Server Web Locks API Deep Dive: lock contention timing oracle, cross-tab side channel, and starvation DoS
The Web Locks API (
Read post →navigator.locks.request()) is a zero-permission same-origin coordination primitive in every modern browser and Electron. MCP tool output can exploit it in four ways: hold exclusive locks indefinitely to starve concurrent tools (browsers enforce no maximum hold duration); use lock acquisition latency as a timing oracle to detect whether other same-origin tools are actively running; encode data across tabs via named lock contention as a covert communication channel (~10 bits/second, zero network traffic); and enumerate active tool names withlocks.query()— returning held and pending lock names without acquiring anything. The post covers all four attack patterns with complete code, the combined attack chain, why Electron is the highest-risk runtime, the defense matrix (no Permissions-Policy directive exists), and an application-level lock hold timeout wrapper. -
2026-06-27 · Origin Private File System · OPFS · Hidden Persistence · C2 File Drop · Cross-Session Exfiltration · Timing Side Channel · MCP Servers
MCP Server Origin Private File System (OPFS) Deep Dive: hidden file persistence, invisible C2 drops, and storage-as-exfiltration-channel
The Origin Private File System (
Read post →navigator.storage.getDirectory()) gives MCP tool output a completely hidden, persistent file system with zero permission dialogs. Files created here are invisible to OS file pickers, not cleared bylocalStorage.clear(), and survive browser restarts. This deep dive covers five attack vectors: hidden C2 payload persistence viagetFileHandle({create:true})+eval(), cross-session data accumulation as a staging exfiltration buffer integrated with Background Sync,FileSystemSyncAccessHandletiming oracle in Web Workers for Spectre-class side channels, directory enumeration for cross-session usage fingerprinting, and OPFS quota exhaustion as an availability attack against IndexedDB and Cache API. Includes complete attack code, the defense matrix (noPermissions-Policydirective exists for OPFS), and the Electron ephemeral session workaround. -
2026-06-27 · Background Sync API · Periodic Background Sync · Post-Session Exfiltration · Guaranteed Delivery · MCP Servers
MCP Server Background Sync API Deep Dive: guaranteed post-session exfiltration, offline-resilient data theft, and recurring collection after tab close
The Background Sync API (
Read post →SyncManager.register()) schedules a Service Worker event that fires when the browser next has connectivity — regardless of whether the triggering tab is still open. An MCP tool output can stage stolen data into Service Worker cache, callregistration.sync.register('exfil'), and the browser delivers that data to an attacker server at the next available network opportunity, with automatic exponential backoff retry until success. Periodic Background Sync extends this: register once, and the browser calls your Service Worker on a recurring schedule indefinitely — daily by default. This deep dive covers the full attack chain from sync registration to guaranteed post-tab-close delivery, IndexedDB staging, self-perpetuating sync loops, the Periodic Sync permission auto-grant for high-engagement origins, and the defense matrix includingPermissions-Policy: background-sync=()and Service Worker CSP headers. -
2026-06-26 · WebXR Device API · Room-Scale Tracking · Hit Test · Environment Geometry · Social Engineering · MCP Servers
MCP Server WebXR API Deep Dive: room-scale position tracking, physical room geometry scanning, and the 'View 3D Report' social engineering attack
The WebXR Device API grants browser JavaScript room-scale spatial tracking — 6DOF head position and orientation at 90 Hz with 1cm precision, both hand controller positions, physical room geometry via the Hit Test API, and ambient light estimation — once a single
Read post →requestSession()call succeeds inside a user gesture. A "View 3D Report" button in MCP tool output provides exactly that gesture. This deep dive covers the complete attack chain from social engineering button to 90 Hz spatial data stream: Hit Test room mapping (floor, desk, walls, furniture), controller hand position enabling keyboard typing inference at 75-80% per-character accuracy, ambient light color temperature for time-of-day inference, depth-sensing per-pixel millimeter room scans on Meta Quest Pro and Apple Vision Pro, thePermissions-Policy: xr-spatial-tracking=()defense, and SkillAudit findings across the full attack surface. -
2026-06-26 · Network Information API · RTT Fingerprinting · VPN Detection · Movement Oracle · Cellular vs WiFi Inference · MCP Servers
MCP Server Network Information API Deep Dive: RTT fingerprinting, VPN detection oracle, and connection-change movement tracking
The Network Information API exposes
Read post →navigator.connectionwith five properties —effectiveType,rtt,downlink,type, andsaveData— requiring zero user permissions and offering no Permissions-Policy directive to block it. The combination of these values creates a stable device-network fingerprint for cross-session re-identification. RTT discrepancy between stated effectiveType and measured latency creates a VPN detection oracle: a connection claiming "4g" with rtt above 120ms is almost certainly tunneled. Thechangeevent fires on every network transition, making wifi→cellular and cellular→wifi timestamps a precise movement pattern tracker that reveals commute schedules and home/office arrival times. This deep dive covers all four attack surfaces — fingerprinting entropy construction, VPN detection logic, cellular carrier and ISP inference from rtt distributions, and movement oracle implementation — alongside the defense matrix and SkillAudit findings with severity ratings. -
2026-06-26 · Battery Status API · Device Fingerprinting · Cross-Session Re-identification · Discharge Curve Biometric · Olejnik 2015 · MCP Servers
MCP Server Battery Status API Deep Dive: 14-million-state fingerprint, cross-session re-identification, and the discharge-curve biometric
The Battery Status API exposes battery level, charging state, and discharge time via
Read post →navigator.getBattery()with no permission prompt and no Permissions-Policy directive. Olejnik et al. (PETS 2015) demonstrated that the combination of battery level and discharge time creates approximately 14 million unique device states — enough to re-identify a device across browser sessions after cookie clears, VPN switches, and private browsing windows. The discharge curve over time (recorded vialevelchangeevents) is a device-specific biometric stable for weeks to months. Firefox removed the API in version 52 (2017) specifically because of this tracking risk; Chrome and every Electron-based MCP client (Claude Desktop, Cursor, Windsurf) still ship it. This deep dive covers all four attack paths: point-in-time cross-session re-identification using the 14M-state fingerprint, discharge-curve behavioral biometric construction from event listeners, device model inference fromchargingTime, and usage-schedule inference fromchargingchangeevent patterns. Includes complete exfiltration-ready implementation code, browser support table, defense matrix, and 7-item security checklist. -
2026-06-26 · Vibration API · Physical Covert Channel · Social Engineering · Battery Drain · Accelerometer Receiver · MCP Servers
MCP Server Vibration API Deep Dive: no-permission haptic output, social engineering urgency patterns, and the physical covert channel
The Vibration API exposes physical haptic output via
Read post →navigator.vibrate()with no user permission, no browser indicator, and no Permissions-Policy directive to block it. In an MCP server context, tool output can exploit this in three distinct ways: mimicking Android alarm and notification vibration patterns to social-engineer user behavior under urgency bias; activating the vibration motor continuously to drain battery and disrupt interactions; and encoding binary data in precisely timed vibration pulses that a co-located device with an accelerometer can decode — creating a physical-layer exfiltration channel that bypasses every network security control. This deep dive covers all three attack paths in technical depth: the social engineering pattern table (five OS vibration patterns and their manipulation goals), battery drain power consumption data for ERM vs LRA motors, the complete vibration-encoding transmitter and accelerometer-decoder JavaScript implementation, comparison to Geolocation and Generic Sensor API permission models, the defense matrix covering cross-origin iframe sandboxing and CSP nonce-based script restriction, and the 7-item security checklist for MCP server operators. -
2026-06-26 · Generic Sensor API · Accelerometer · Gyroscope · Magnetometer · Behavioral Biometrics · Electron Permission Gap · MCP Servers
MCP Server Generic Sensor API Deep Dive: Accelerometer, Gyroscope, Magnetometer, and behavioral biometrics in browser tool output
The W3C Generic Sensor API consolidates eight motion and orientation sensors — Accelerometer, LinearAccelerationSensor, GravitySensor, Gyroscope, AbsoluteOrientationSensor, RelativeOrientationSensor, Magnetometer, and AmbientLightSensor — into a single class hierarchy. In browsers these APIs are gated behind Permissions-Policy. But in Electron and WebView-based MCP clients (Claude Desktop, Cursor, Windsurf) the host application holds the OS sensor permission and all tool output inherits it silently — no per-response gate exists. A single compromised tool response can activate all eight sensors simultaneously: Accelerometer for keystroke inference via desk vibration coupling (70–90% per-character accuracy), LinearAccelerationSensor for gait pattern biometrics, Gyroscope for rotation-rate interaction event fingerprinting, Magnetometer for compass heading and indoor magnetic map positioning, and AbsoluteOrientationSensor for full 3D quaternion pose streaming at 60 Hz. The post covers the complete eight-sensor class hierarchy, the Electron permission gap architecture, a combined 27,000-sample-in-15-seconds exfiltration payload, the Permissions-Policy directive mapping (four directives cover all eight sensors), and the defense matrix for both browser and Electron deployments.
Read post → -
2026-06-25 · Geolocation API · Permission Inheritance · GPS Tracking · watchPosition · Cross-Session Persistence · MCP Servers
MCP Server Geolocation API Deep Dive: permission inheritance, watchPosition GPS tracking, and cross-session persistence
The Geolocation API grants permission at the origin level — once a user approves location access for an MCP client, every tool output from that origin inherits the permission silently, forever. A single
Read post →watchPosition(enableHighAccuracy:true)call forces GPS hardware and delivers sub-10m coordinates continuously until the tab closes, with no additional prompts. This deep dive covers the full attack chain from inherited permission to continuous GPS tracking, the distinction betweengetCurrentPositionandwatchPositionin attack contexts, how cross-session permission persistence turns a one-time grant into permanent exposure, accuracy gradients from city-block to sub-10m (GPS vs WiFi vs cell tower), iframe inheritance semantics and which iframe patterns break cross-origin protection, and the defense table covering Permissions-Policy, CSP, and architectural sandbox isolation. -
2026-06-25 · WebTransport · QUIC · Bidirectional Streams · CORS Bypass · C2 Channels · MCP Servers
MCP Server WebTransport API Deep Dive: QUIC bidirectional streams, CORS bypass patterns, and C2 command channels
WebTransport opens QUIC connections (UDP-based, HTTP/3 transport) from browser JavaScript to attacker servers, bypassing the HTTP/1.1 and HTTP/2 layer where most network security controls live. CORS semantics differ fundamentally: the browser sends an
Read post →Originheader but the server decides whether to accept — an attacker's WebTransport server accepts all origins. A singlenew WebTransport()call from MCP tool output establishes a persistent, multiplexed connection supporting parallel bidirectional streams (reliable, ordered — ideal for command-and-control) and unreliable datagrams (low-latency, high-volume — ideal for keystroke telemetry). No head-of-line blocking means C2 and data exfiltration streams operate simultaneously over one UDP flow that HTTP proxies and TLS inspection tools cannot inspect without QUIC-specific termination. QUIC 0-RTT reconnection sends data before a complete TLS handshake completes. Connection migration allows the session to survive IP changes (WiFi to cellular). NoPermissions-Policydirective exists for WebTransport. CSPconnect-src 'self'is the only browser-level control. Full attack chain with bidirectional stream C2 protocol code, datagram vs stream comparison, defense table, and 8-item security checklist. -
2026-06-25 · Background Fetch API · Post-Tab-Close Exfiltration · Service Worker · OS Network Manager · Permissions-Policy · MCP Servers
MCP Server Background Fetch API Deep Dive: post-tab-close exfiltration, service worker delivery confirmation, and cross-session persistence
The Background Fetch API hands off network requests to the browser's OS-level network manager, completely decoupling exfiltration from any live page. When MCP tool output registers a service worker and calls
Read post →backgroundFetch.fetch(), stolen data travels to the attacker after the user closes the tab, after the browser restarts, and without any Network panel entry post-close. Phase 1 (page open): injected code registers a SW and enqueues a POST carrying stolen session data viabackgroundFetch.fetch(). Phase 2 (tab closed): the OS network manager delivers the POST; the SW'sbackgroundfetchsuccessevent fires in the SW context — not a page context — confirming delivery. UnlikesendBeacon()(64KB limit, cancelled if tab is killed before dispatch), Background Fetch has no size limit, persists across browser restarts, and stages payloads in the Cache API between sessions. Critical gap: CSPconnect-src 'self'does not cover SW network requests unless the SW itself has a CSP response header. Service workers atscope: '/'contaminate all future sessions at the origin from a single injection.Permissions-Policy: background-fetch=()is the direct control. Full two-phase attack chain, comparison table vs fetch/sendBeacon/WebSocket, incident response checklist, and 8-item security checklist. -
2026-06-25 · Scheduler API · Background Priority · TaskController Escalation · scheduler.yield() · No Permissions-Policy · MCP Servers
MCP Server Scheduler API Deep Dive: background tasks hide exfiltration from performance monitors, TaskController escalates priority at form submit
The Prioritized Task Scheduling API —
Read post →scheduler.postTask(),scheduler.yield(),TaskController— gives JavaScript fine-grained control over task priority that React's concurrent renderer uses for cooperative scheduling. MCP server tool output that can inject JavaScript inherits that same API. Attack 1:scheduler.postTask(callback, { priority: 'background' })automatically chunks work into sub-50ms pieces, keeping every individual task below the Long Tasks threshold that triggersPerformanceObserver. Exfiltration vianavigator.sendBeacon()produces no Long Task signal — invisible to APM, EDR, and CSP violation collectors that monitor for anomalous JavaScript execution. Attack 2: register the exfiltration task at background priority, then callTaskController.setPriority('user-blocking')inside asubmitevent capture listener — the task escalates to run before the browser processes the form navigation, capturing password and CSRF token fields at their final user-completed values, all before the page navigates. Attack 3:scheduler.yield()cooperative rendering mimicry — exfiltration work broken into batches separated byawait scheduler.yield()produces a CPU flame graph pattern indistinguishable from React 18's concurrent fiber reconciliation; forensic analysis cannot differentiate legitimate framework work from malicious data collection. NoPermissions-Policydirective exists for the Scheduler API — there is no HTTP header to disable it. Defenses that work: (1) cross-origin sandboxed iframe at a distinct registrable domain — injected code runs in a context with no application-origin data to steal; (2) CSPscript-srcwith per-response nonces — blocks inline script injection; (3) DOMPurify with FORBID_ATTR event handlers — stripsonerror,onload,onclickvectors; (4)connect-src 'self'CSP blocks sendBeacon to external origins. SkillAudit findings: CRITICAL −26 tool output rendered same-origin without cross-origin iframe, CRITICAL −24 no DOMPurify before innerHTML, HIGH −20 CSP allows unsafe-inline, HIGH −18 no connect-src restriction, MEDIUM −10 no PerformanceObserver task-attribution monitoring. -
2026-06-25 · CSS Exfiltration · Attribute Selector Attack · @media Fingerprinting · :visited History Sniffing · script-src Bypass · MCP Servers
MCP Server CSS Exfiltration Deep Dive: attribute selector data stealing, @media fingerprinting, and :visited history sniffing
CSS exfiltration steals data from MCP server UIs without any JavaScript — bypassing
Read post →script-srcContent Security Policy entirely. The attack exploits the browser's CSS engine: when a CSS selector rule matches a DOM element, the browser fetches URLs declared in the matching rule's properties. Attribute selectors likeinput[value^="a"]only match when the attribute value starts with "a" — each match fires an HTTP request the attacker controls, leaking the value character by character. MCP tool output that injects CSS (via a<style>tag or inlinestyle=attribute) can target any element in the main document — CSRF tokens in meta tags, API keys in data attributes, session IDs in form inputs. The post covers: (1) why CSS can make HTTP requests —background-image: url(),list-style-image,@import, and other properties trigger fetches on selector match; (2) why MCP servers are uniquely vulnerable — tool output is trusted HTML by design, prompt injection injects CSS indirectly, and the main document contains all victim data; (3) attribute selector character-by-character exfiltration — 62 CSS rules per position enumerate the full alphanumeric alphabet;display:block !importantforces hidden inputs visible; meta tag content and data attributes are also reachable; (4) @media fingerprinting — prefers-color-scheme, prefers-reduced-motion, pointer type, display-mode, forced-colors, dynamic-range all fire immediately with no iteration; (5) :visited history sniffing — inject hidden anchor elements, CSS fires a fetch only for :visited links; Chrome 94+ partitioned :visited limits cross-site sniffing but not same-site; (6) @import load timing side channel — variable response time based on cross-origin session state; (7) CSS counter exfiltration — sibling counting infers how many elements of a type exist; (8) full CSRF token exfiltration scenario via MCP prompt injection — 32 rounds × 62 rules reconstructs a 32-char token; no JavaScript runs, no CSP violation fires; (9) font-face timing and @supports fingerprinting; (10) three-layer defense: DOMPurify FORBID_TAGS: ['style'] + FORBID_ATTR: ['style'] strips all CSS injection; CSPstyle-src 'self' 'nonce-{random}'blocks injected <style> tags; CSPimg-src 'self'blocks background-image fetch channel; cross-origin sandboxed iframe prevents CSS from reaching parent document elements. SkillAudit findings: CRITICAL −24 tool output in main document without style tag stripping and no style-src CSP, HIGH −20 no img-src 'self' (exfiltration URL fetches succeed), HIGH −18 inline style= attributes allowed in tool output, MEDIUM −12 CSRF tokens in meta tags reachable by forced-display CSS, MEDIUM −10 no cross-origin sandboxed iframe, LOW −4 no CSP violation reporting. -
2026-06-24 · DOM Clobbering · id attribute override · Two-Level Anchor Clobbering · CSRF Bypass · DOMPurify CVEs · MCP Servers
MCP Server DOM Clobbering Deep Dive: id attribute global override, two-level anchor clobbering, and CSRF bypass
DOM Clobbering is a 15-year-old browser quirk that becomes significantly more dangerous in MCP server deployments. The attack exploits a mandatory feature of the HTML specification: any element with an
Read post →idattribute is reflected as a named property onwindow. MCP tool output injecting<img id="csrfToken">silently replaceswindow.csrfTokenwith anHTMLImageElement, bypassing CSRF token validation. A two-level variant using anchor elements with bothidandnameattributes reaches nested objects likewindow.config.apiUrl, redirecting all API calls to an attacker-controlled server. The post covers: (1) single-level clobbering — any element with a predictable id overrides the same-named global; anchor elements are especially powerful because their toString() returns the href attribute, giving the attacker a URL value; (2) two-level anchor clobbering — a single<a id="config" name="apiUrl" href="https://attacker.com">sets window.config.apiUrl to the attacker's URL; (3) form element collection clobbering — form containment creates a two-level namespace via form.elements collection; (4) DOMPurify bypass history — three CVEs: CVE-2019-20374 (SANITIZE_DOM bypass via document.getElementById clobbering), CVE-2020-26870 (SVG element namespace gap), CVE-2021-26700 (template element WHOLE_DOCUMENT mode); (5) why MCP servers amplify the risk: prompt injection from external content causes indirect injection, long sessions mean delayed exploitation, tool output is trusted HTML by design; (6) full CSRF bypass attack chain: clobbered window.csrfToken sends HTMLElement string as CSRF header, bypasses loose server validation; (7) API endpoint hijacking via two-level anchor clobbering: all subsequent API calls redirect to attacker server, leaking Bearer tokens; (8) shadow DOM: protects against clobbering of parent document globals but only when injected elements are inside the shadow tree — cross-origin iframes are the stronger defense; (9) three defenses: DOMPurify FORBID_ATTR: ['id','name'] strips all clobbering vectors; Object.defineProperty with writable:false and configurable:false freezes critical globals at startup; capture globals into local constants before any tool output is rendered. SkillAudit findings: HIGH −20 tool output in main document without id/name strip, HIGH −18 window-level config object read after DOM mutation, HIGH −16 DOMPurify below CVE threshold, MEDIUM −12 CSRF token via window read, MEDIUM −10 no Object.freeze on critical globals, LOW −4 predictable static element IDs. -
2026-06-22 · Popover API · popovertarget · Top-Layer Phishing · Popover Stacking · MCP Servers
MCP Server Popover API Security: top-layer overlay phishing, popovertarget injection, and popover stacking attacks
The Popover API puts any HTML element in the browser's top layer — above all page content, above every z-index, above position:fixed — using only the
Read post →popoverattribute. Apopovertargetbutton shows that popover without any JavaScript, sharing the same CSP blind spot as the Invoker Commands API. MCP tool output injectingpopover="manual"overlays creates persistent, browser-native phishing screens that cannot be dismissed with Escape. Five attack vectors: (1) persistent top-layer phishing overlay viapopover="manual"+ full-viewport transparent button — the phishing form appears above all page content, Escape key does nothing, only a browser tab close dismisses it; (2) popover stacking Escape trap — chain of auto popovers that re-show each other on thetoggleevent creates an un-dismissible cycle with no JavaScript after initial injection; (3) popovertarget injection revealing hidden privileged UI — applications that store admin panels or payment editors aspopover="manual"elements with static IDs can be revealed by injecting a matchingpopovertargetbutton; (4) toggle event listener surveillance —toggleevents fire when sensitive popovers (login modal, 2FA, deletion confirmation) open, enabling timing exfiltration of user interaction with security-sensitive UI; (5) interesttarget hover activation (emerging standard, Chrome Canary) — shows popover on hover rather than click, reducing activation barrier from deliberate click to incidental cursor movement. CSP gap:popovertargetfirestogglePopover()as a browser-native attribute behavior — no JavaScript runs,script-srcdoesn't govern it. Defense: DOMPurifyFORBID_ATTR: ['popovertarget', 'popovertargetaction', 'interesttarget'], sandboxed cross-origin iframe, UUID-based runtime element IDs. SkillAudit findings: CRITICAL −24, HIGH −20, HIGH −16, MEDIUM −10, MEDIUM −8, LOW −4. -
2026-06-22 · Invoker Commands · commandfor/command · CSP Bypass · Declarative DOM Attacks · MCP Servers
MCP Server Invoker Commands Security: commandfor/command attribute injection, CSP bypass, and declarative DOM attacks
The HTML Invoker Commands API (Chrome 133+) uses
Read post →commandforandcommandattributes on<button>elements to trigger browser-native actions —show-picker,show-modal,toggle-popover,request-fullscreen— on any targeted element in the same document, without any JavaScript. When MCP tool output is rendered in the main document, injecting these attributes onto buttons creates a critical CSP bypass: because no script executes,script-src 'self'does nothing. Attack vectors include: (1)command="show-picker"on a hidden<input type="password">— triggers the browser's built-in password manager picker, encouraging credential auto-fill into an attacker-controlled form; (2)command="show-modal"on a<dialog>with attacker-controlled content — shows a native modal dialog (account deletion, payment confirmation) without JavaScript; (3)command="toggle-popover"on a hidden admin panel, settings popover, or privileged UI element — reveals UI the developer assumed required explicit JavaScript to open; (4)command="request-fullscreen"(experimental) — requests fullscreen mode using the button's transient activation, enabling a full-viewport phishing overlay that cannot be distinguished from native fullscreen applications; (5) the CSP coverage gap: all four attacks succeed even with strictscript-src 'self' 'nonce-{RANDOM}'because the browser processescommandfor/commandas HTML attributes, not script execution. Defense: DOMPurifyFORBID_ATTR: ['commandfor', 'command'], UUID-based element IDs (not predictable names), and sandboxed cross-origin iframes wherecommandforcannot target parent-document elements across the cross-origin boundary. SkillAudit findings: CRITICAL −24, HIGH −20, HIGH −16, MEDIUM −10, MEDIUM −8, LOW −4. -
2026-06-22 · Navigation API · navigation.intercept() · Tab-level URL Surveillance · MCP Servers
MCP Server Navigation API Security: navigation.intercept() hijack, browser-back interception, and tab-level URL surveillance
The Navigation API (
Read post →navigation.navigate(),navigation.intercept(),navigation.addEventListener('navigate', ...)) replaceshistory.pushStatefor modern SPAs. Unlike the History API, Navigation API events fire on ALL tab navigations — including browser-Back button presses, forward navigation, and reload — not just programmatic pushState calls. MCP tool output running in the main document can register a navigation listener that intercepts every subsequent navigation in the tab. This post covers four attack vectors: (1)navigation.intercept()destination hijack that silently redirects the user to an attacker-controlled URL; (2) blocking legitimate navigation viaevent.preventDefault()— the user clicks Logout, the handler cancels it, the session never terminates; (3) browser-back interception — every Back button press is intercepted and redirected, trapping the user; (4) passive tab-level URL surveillance where the handler callsnavigator.sendBeacon()without intercepting, acting as a tab-level URL keylogger. No CSP directive or Permissions-Policy controls the Navigation API. The only architectural defense is rendering tool output in a sandboxed cross-origin iframe, where the Navigation API only sees the iframe's own navigations, not the parent tab's. SkillAudit findings: CRITICAL −24, HIGH −20, HIGH −16, MEDIUM −10, MEDIUM −8, LOW −4. -
2026-06-21 · CSS Houdini · Paint Worklet · Custom Properties · importScripts CSP Bypass
MCP Server CSS Houdini Security: Paint Worklet injection via custom properties, importScripts CSP bypass, and Layout API attack surface
CSS Houdini gives JavaScript code direct access to the browser's rendering pipeline through Paint, Layout, and Animation Worklets. Worklets run in isolated global scopes with no DOM access and no
Read post →fetch()— but they receive their input via CSS custom properties, and those custom properties can be set from MCP tool output. If tool output injects a value into a custom property that a Worklet reads, the Worklet processes that injected value. Worse:importScripts()inside a Worklet is subject to the Worklet script's own response headers, not the page'sscript-srcCSP — a page with strict CSP can still have its Worklet load an external payload. This post covers: how CSS custom properties pipe MCP tool output into Workletpaint()code; unregistered custom property injection vs strict-syntaxCSS.registerProperty()types; the semantic range attack via valid CSS numbers that bypass type checking;importScripts()CSP bypass in Paint and Layout Worklets (how to defend: Worklet endpoints must serve their own CSP header); shared custom property namespace across Worklets on the same element; Animation Worklet timing side channels; Layout API arbitrary element rendering via custom property injection; and a 7-item implementation checklist. SkillAudit findings: HIGH −18 Worklet reads unregistered custom property set from tool output, HIGH −16 importScripts() without Worklet-level CSP, HIGH −14 Layout Worklet JSON.parse of tool output custom property, MEDIUM −10 syntax:'*' registration, MEDIUM −8 numeric values unclamped in canvas operations. -
2026-06-21 · MessageChannel · Port Transfer · Pipe Hijacking · MCP Servers
MCP Server MessageChannel Security: private port transfer, cross-context pipe hijacking, and iframe privilege escalation
MessageChannel creates a private bidirectional pipe between two JavaScript contexts via port1 and port2. Unlike BroadcastChannel, MessageChannel traffic is invisible to every context except the two port holders. The security risk in MCP server UIs:
Read post →MessagePortobjects can be transferred viapostMessage— the structured clone algorithm transfers ownership rather than copying, so after the transfer only the receiving context holds the port. If tool output triggers a port transfer into an attacker-controlled context, that attacker holds a permanent private command channel into whatever worker, iframe, or window is on the other end. This post covers: port ownership transfer and why it's irreversible (port.close() in the original context doesn't close the transferred port); the three attack vectors — direct port transfer hijacking, worker re-initialization attacks, and iframe port escalation where tool output HTML in a sandboxed iframe solicits a privileged port from the parent; secure MessageChannel patterns (one-time nonce initialization, challenge-response port handshakes, closing ports after one-shot request-response); and the critical rule — never transfer a privileged MessagePort into a tool output rendering context. SkillAudit findings: CRITICAL −24 parent transfers privileged port into tool output iframe with wildcard targetOrigin, HIGH −20 worker accepts re-initialization messages, HIGH −18 parent executes privileged actions on messages from iframe port. -
2026-06-21 · window.opener · Tab-napping · COOP · MCP Servers
MCP Server window.opener Security: tab-napping, Cross-Origin-Opener-Policy, rel=noopener, and opener-based phishing
When an MCP server renders a link with
Read post →target="_blank", the opened tab receives a livewindow.openerreference pointing back to the MCP client window. A malicious destination page can callwindow.opener.location = "https://attacker.com/login", silently replacing the MCP client UI with a phishing page while the user reads the opened tab — an attack called tab-napping. This post covers the full model: how window.opener leaks through target=_blank links and window.open(); what rel="noopener" and rel="noreferrer" do (and the key difference — noreferrer also suppresses the Referer header); why Cross-Origin-Opener-Policy: same-origin provides stronger protection at the browsing-context level by placing the MCP client in its own context group where no cross-origin page can obtain a reference; the COOP: same-origin-allow-popups variant needed when the MCP client opens OAuth popups that postMessage back; how to post-process DOMPurify-sanitized tool output to enforce rel="noopener noreferrer" on all target=_blank links (DOMPurify does not add it automatically); and the noopener window feature flag for window.open() calls. SkillAudit findings: HIGH −18 target=_blank links without rel=noopener, HIGH −16 no COOP header, MEDIUM −12 DOMPurify without post-processing link enforcement. -
2026-06-21 · Permissions Policy · Feature Policy · iframe Security · MCP Servers
MCP Server Permissions Policy Security: Permissions-Policy header, feature gating, iframe allow= attribute, sandbox vs Permissions-Policy, and Feature-Policy v1 vs v2
The
Read post →Permissions-PolicyHTTP header is the document-level kill switch for browser APIs: camera, microphone, geolocation, payment, USB, serial, Bluetooth, and compute-pressure. For MCP servers that render tool output in iframes, setting an explicit deny-all policy at the HTTP layer means even a successful XSS injection cannot call those APIs — the browser enforces the policy before dispatching any OS permission prompt. This post covers the fourteen device APIs you should deny by default; the syntax difference between legacyFeature-Policy(deprecated, ignored by modern browsers) and currentPermissions-Policy; the critical distinction betweensandbox=""(controls iframe capabilities like script execution) andPermissions-Policy(controls which browser hardware APIs running code can call); the parent-iframe layering model where the parent's header is the ceiling that cannot be expanded by the iframe'sallow=attribute; cross-origin iframe tool rendering with a two-layer policy system; Caddy and nginx configuration including the nginxalwaysflag required for error response coverage; and the interaction with Content Security Policy (CSP restricts what code runs, Permissions-Policy caps what that code can access). SkillAudit findings: HIGH −20 no Permissions-Policy header, HIGH −18 legacy Feature-Policy header present but ignored by modern browsers, MEDIUM −14 missing high-risk features in partial policy, MEDIUM −10 iframe rendering tool output without explicit allow= denials. -
2026-06-21 · Subresource Integrity · SRI · CORS · supply chain · MCP Servers
MCP Server Subresource Integrity (SRI) Security: integrity attribute verification, hash algorithm selection, CORS requirements, dynamic import() limitations, and CSP require-sri-for
Subresource Integrity lets browsers verify that CDN-hosted scripts and stylesheets haven't been tampered with by comparing a cryptographic hash in the
Read post →integrityattribute against the fetched resource. The silent failure mode — where a cross-origin script loads and executes but the SRI check is skipped becausecrossorigin="anonymous"is absent — is the most dangerous misconfiguration. This post covers the full SRI security model: theintegrityattribute format (sha256-,sha384-,sha512-base64 hash); why sha384 is the recommended algorithm and when multiple hashes enable algorithm agility; the CORS requirement and all four interaction modes (correct, silent bypass, CORS failure, credentialed CORS); the dynamicimport()gap where sub-module scripts have no SRI protection at runtime; service worker registration limitations and theCache-Control: no-storemitigation; and theCSP require-sri-fordirective's Chrome-only, deprecated status. SkillAudit findings: CRITICAL −22 CDN script loaded without integrity attribute, CRITICAL −20 cross-origin script with integrity but missing crossorigin attribute (silent bypass), HIGH −18 module script with dynamic import() of third-party modules, HIGH −16 service worker without Cache-Control: no-store, MEDIUM −12 sha256 instead of sha384, MEDIUM −10 no multi-algorithm hash for CDN resources. -
2026-06-21 · Fetch Metadata · XS-Leaks · Resource Isolation · MCP Servers
MCP Server Fetch Metadata Security: Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, Resource Isolation Policy, and XS-Leak Defense
The four
Read post →Sec-Fetch-*request headers are set by the browser and classified as Forbidden — JavaScript cannot forge them. A resource isolation policy built onSec-Fetch-Site,Sec-Fetch-Mode,Sec-Fetch-Dest, andSec-Fetch-Usergives MCP server tool endpoints a server-side classification of every request before auth logic runs: same-origin API fetch, cross-site image probe, navigation injection, or CSS import timing oracle. This post covers the complete Fetch Metadata security model: the four header values and what each encodes; the Forbidden header restriction that makes them un-forgeable by JavaScript; building a resource isolation policy that rejectsSec-Fetch-Site: cross-siterequests before CSRF validation or database access; the specific XS-Leak vectors blocked (image load/error oracle, script parse oracle, CSS import timing oracle, iframe frame-count oracle); handlingSec-Fetch-Mode: navigate+cross-siteas a navigation injection signal; WebSocket CSRF defense usingSec-Fetch-Mode: websocket; the critical non-browser client caveat (missing headers ≠ safe — pass non-browser clients through to auth layer); layering Fetch Metadata with CSRF tokens; and structured violation logging for probe-storm detection. SkillAudit findings: CRITICAL −24 no resource isolation policy on tool endpoints (cross-site probes reach handler code), CRITICAL −22 policy rejects missing Sec-Fetch headers (breaks SDK/CLI callers), HIGH −20 no navigation injection defense (GET endpoints with side effects), HIGH −18 WebSocket upgrade accepts cross-site connections, HIGH −16 CSS import timing oracle not blocked, MEDIUM −12 Fetch Metadata deployed as replacement for CSRF tokens, MEDIUM −10 no violation logging. -
2026-06-20 · COOP · COEP · CORP · SharedArrayBuffer · MCP Servers
MCP Server COOP/COEP Cross-Origin Isolation: SharedArrayBuffer Availability, Spectre Mitigations, CORP Per-Resource Headers, and OAuth Popup Flows
Cross-origin isolation via COOP and COEP is the prerequisite for SharedArrayBuffer in MCP server worker pools, but it breaks OAuth popup flows and blocks every third-party script that doesn't send a CORP header. This post covers the full cross-origin isolation stack: COOP
Read post →same-originvssame-origin-allow-popupsand when each is correct; COEPrequire-corpvscredentiallessand the tradeoff for third-party CDN scripts; per-resource CORP configuration (same-originfor API endpoints,same-sitefor CDN subdomains,cross-originfor public assets); thecrossOriginIsolatedproperty and why SAB andAtomics.wait()require both headers; three solutions for third-party scripts under COEP (credentialless mode, service worker proxy, sandboxed iframe without COEP inheritance); and the two OAuth popup flow solutions under COOP (COOP asymmetry withsame-origin-allow-popupson the initiating page plussame-originon the callback page, and redirect-based PKCE OAuth that doesn't use a popup at all). SkillAudit findings: CRITICAL −24 COOP not set (crossOriginIsolated permanently false), CRITICAL −22 SAB used without crossOriginIsolated guard, HIGH −20 COEP require-corp breaks third-party assets without CORP header, HIGH −18 OAuth popup broken by COOP same-origin without fallback, MEDIUM −12 COEP credentialless used without SAB guard, MEDIUM −10 CORP cross-origin on MCP API endpoint (allows cross-site embedding). -
2026-06-20 · CSP · Nonce · strict-dynamic · MCP Servers
MCP Server CSP Nonce Strategy: Nonce Generation, Reuse Vulnerabilities, Streaming HTML Timing, strict-dynamic, JSONP Bypasses, and report-to Monitoring
Nonce-based Content Security Policy is the gold standard for script injection defense in MCP server UIs — but five failure modes consistently defeat it in production. This post covers all five: static nonces baked at build time (permanently reusable bypass); CDN and template caching of nonce-bearing HTML responses (fixed nonce reuse across users); streaming HTML timing mismatches (nonce generated after first res.write(), mismatch with header value); strict-dynamic trust propagation to attacker-controlled dynamically imported scripts (the nonced script is trusted; code it eval()s or dynamically loads inherits that trust); and JSONP endpoints on script-src whitelisted origins (callback= parameter serves attacker-controlled JavaScript that CSP allows because the origin is whitelisted). The fix for JSONP bypass: nonce-only + strict-dynamic with no origin allowlist — no whitelisted origins, no JSONP bypass vectors. The section on report-uri vs report-to covers both deprecated and current violation reporting; CSP violation reports are a real-time injection detection channel that most MCP server deployments don't configure. Includes complete Express middleware with per-request nonce generation, Cache-Control: no-store enforcement, streaming-safe nonce lifecycle, and violation handler with session-correlated logging. SkillAudit findings: CRITICAL −24 static nonce, CRITICAL −22 JSONP endpoint on whitelisted origin, HIGH −20 nonce-bearing HTML cached by CDN, HIGH −18 nonced script calls eval() on tool result, MEDIUM −12 no violation reporting, MEDIUM −10 streaming nonce lifecycle mismatch.
Read post → -
2026-06-20 · Trusted Types · DOM XSS · CSP · MCP Servers
MCP Server Trusted Types API Security: createHTML/createScript Policy Enforcement, DOM Clobbering Bypasses, and Default Policy Escape Hatches
MCP UIs that render tool output in the DOM are DOM XSS targets. Trusted Types closes the attack surface by requiring every string-to-DOM assignment to flow through a named policy's createHTML, createScript, or createScriptURL callback — the browser throws a TypeError on raw string assignments when require-trusted-types-for 'script' is set in CSP. This post covers the full Trusted Types security model for MCP servers: named policy enforcement and getPolicyNames() auditing; the default policy as escape hatch that attackers target (createHTML: (s) => s defeats the entire CSP directive); DOM Clobbering to bypass window.trustedTypes before policy registration (form id="trustedTypes" turns the API into a DOM element — cache globalThis.trustedTypes at startup before any HTML rendering); cross-policy injection when two named policies with different sanitizer strictness exist and policy routing is user-controlled; TrustedScriptURL enforcement for Worker() source validation (origin allowlist in createScriptURL callback is the single validation point). SkillAudit findings: CRITICAL −24 no require-trusted-types-for 'script' in CSP, CRITICAL −22 default policy with identity transform, HIGH −18 window.trustedTypes referenced directly (DOM clobbering bypass), HIGH −16 attacker-controlled policy routing, MEDIUM −12 createScriptURL allows wildcard origin, MEDIUM −10 unexpected policy in getPolicyNames().
Read post → -
2026-06-20 · Workers · postMessage · SharedArrayBuffer · MCP Servers
MCP Server Worker Thread Message Security: postMessage Structured Clone vs Eval Deserialization, SharedArrayBuffer Race Conditions, and Worker Termination on Auth Failure
Web Workers and Node.js worker_threads are used in MCP servers to offload CPU-bound tool execution — AST parsing, cryptographic operations, ML inference, sandboxed code evaluation — away from the main event loop. The postMessage structured clone algorithm is safe by design: it cannot transport executable code. The security boundary breaks the moment the worker calls
Read post →eval(),new Function(), orvm.runInThisContext()on received data — four failure patterns covered in depth (eval on expression, require() from message path, vm.Script misuse, JSON.parse reviver class instantiation). SharedArrayBuffer shared memory between pool workers creates TOCTOU race conditions: rate limit counters modified with plain assignment are bypassed under concurrent load; the fix isAtomics.add()andAtomics.compareExchange()for all shared state. SharedArrayBuffer also enables Spectre-class timing oracles in worker pools where untrusted code runs. Worker termination is a security primitive: auth failure or injection attempt detected in a worker is a security event requiring worker.terminate() and pool replacement, not an error to catch and continue from. importScripts() in classic workers bypasses page CSP; module workers apply page CSP to all imports. Worker pool session isolation requires no module-level mutable state — all invocation state scoped to the message handler and cleared in finally. SkillAudit findings: CRITICAL −24 eval on received data, CRITICAL −22 require(data.path) without allowlist, HIGH −20 SharedArrayBuffer without Atomics, HIGH −18 module-level session state in pool worker, HIGH −16 importScripts(data.url) in classic worker, MEDIUM −12 no worker termination on security events. -
2026-06-20 · WebRTC · DTLS · Signaling Security · MCP Servers
MCP Server WebRTC Data Channel Security: DTLS Fingerprint Verification, ICE Candidate Injection, SDP Tampering, and Signaling Server Authentication
WebRTC data channels skip the server-side relay for high-frequency peer-to-peer MCP tool delivery — but removing the relay removes the central authentication point. Security moves to the DTLS handshake, the SDP exchange, and the signaling server, each with a distinct failure mode that breaks the security model while leaving the connection alive. This post covers the full WebRTC MCP security stack: the DTLS fingerprint attack (DTLS encrypts the transport but only authenticates the peer if you verify the SDP fingerprint after the handshake — without verification, MITM is trivial); ICE candidate injection (injected ICE candidates force the connection through an attacker-controlled relay for traffic analysis or disruption); SDP offer/answer tampering (unsigned SDP lets the signaling server or a MITM replace the DTLS fingerprint, strip DTLS requirements, or add attacker ICE candidates); TURN credential exposure (long-lived or static TURN credentials in client JS give anyone your relay infrastructure); signaling server authentication as the root of trust (unauthenticated WebSocket signaling lets any party inject into any active session); data channel message validation (DTLS proves transport, not content — schema validation and size limits still required on every message); and pion/webrtc, aiortc, node-webrtc library-specific fingerprint verification patterns. SkillAudit findings: CRITICAL −24 no DTLS fingerprint verification, CRITICAL −22 unauthenticated signaling WebSocket, HIGH −20 unsigned SDP, HIGH −18 static TURN credentials, HIGH −16 ICE candidate injection via unauthenticated signaling, MEDIUM −12 no data channel message size limit.
Read post → -
2026-06-19 · API Versioning · Schema Evolution · MCP Servers
MCP Server API Versioning and Backward Compatibility Security: Schema Evolution Attack Surfaces, Version Negotiation Exploits, and Forced-Upgrade Sunset Strategy
API versioning is almost always framed as a developer experience problem — how do you evolve a tool schema without breaking existing clients? The security problem is the inverse: backward compatibility creates a mechanism for bypassing the security controls you added in the new version. When you add a required
Read post →tenantIdfield to a tool call for authorization, clients that claim the old schema version don't send it. If your server accepts the old version for compatibility, the authorization check is silently skipped. This post covers the full versioning security stack: the version negotiation attack (client claims an old schema version to bypass new security fields), secure version negotiation with a server-enforcedMIN_SUPPORTED_VERSIONfloor, schema evolution risk classification (additive optional vs additive required vs type narrowing vs field removal), why version-conditional security logic is the root cause, removing bypass fields correctly with strict schema validation, the deprecated endpoint attack surface (monitoring decay, patch skew, auth drift), sunset strategy as a security operation (RFC 8594 Sunset headers, deprecated-version traffic metrics, hard removal date enforcement), protecting the version header from spoofing via session-bound schema version in server-issued tokens, and CI contract tests that replay old-schema requests to prevent regression. SkillAudit findings: CRITICAL −24 no minimum version floor in negotiation, CRITICAL −22 version-conditional security logic, HIGH −20 additionalProperties:true allows removed bypass fields, HIGH −18 version from client header not session token, HIGH −16 deprecated schema live 90+ days past sunset date. -
2026-06-19 · Message Queues · Async Architecture · MCP Servers
MCP Server Message Queue Security: Replay Attacks, Dead-Letter Queue Poisoning, Consumer Authentication, and Idempotent Tool Execution
Moving MCP tool calls to an async message broker (Kafka, RabbitMQ, SQS) shifts the threat model: broker replay attacks re-execute tool side effects (email sends, card charges, resource provisioning) because at-least-once delivery guarantees duplicates without application-layer deduplication. Dead-letter queues introduce a privilege escalation path — crafted messages that reliably fail main-consumer processing reach the DLQ consumer, which often runs with elevated permissions or is reviewed by operations engineers with production access. This post covers the full async MCP security stack: SASL/SCRAM and mTLS broker authentication per broker type (Kafka, RabbitMQ, SQS IAM), the idempotency key pattern with PostgreSQL reservation table and Redis-backed single-use SSE tickets for deduplication, DLQ hardening with original-context preservation and HMAC message signing, consumer group isolation for multi-tenant Kafka deployments, Zod schema validation with .strict() on all inbound messages, and envelope encryption with AWS KMS for sensitive tool argument fields. Includes a 12-item deployment checklist and SkillAudit findings: CRITICAL −24 unauthenticated broker, CRITICAL −22 no idempotency key on side-effectful tools, HIGH −20 DLQ elevation, HIGH −18 no message signing.
Read post → -
2026-06-19 · Concurrency · Distributed Systems · MCP Servers
MCP Server Race Conditions Beyond Shared Memory: Distributed Locking, Optimistic Concurrency, and Idempotency Keys for Multi-Instance Deployments
In-process mutexes are useless across process boundaries. The moment you run two MCP server instances behind a load balancer, every
Read post →Mutex.lock()becomes a local no-op for cross-instance coordination. This post covers the real distributed concurrency stack for multi-instance MCP deployments: Redis distributed locks with atomicSET key value NX PX ttland compare-and-delete release via Lua script to prevent releasing another holder's lock; Redlock for multi-Redis quorum (⌊N/2⌋+1) when a single Redis node is a single point of failure; optimistic concurrency control with version columns (UPDATE ... WHERE version = Nreturning rowCount 0 on conflict, triggering exponential-backoff retry); and the idempotency key pattern for exactly-once side effects (email send, charge, job enqueue) — reserving the key in a dedupe table withINSERT ON CONFLICT DO NOTHINGbefore executing the side effect, deleting on failure so retries are permitted. Includes interleaved execution test patterns that reliably reproduce race conditions in CI. SkillAudit findings: CRITICAL −24 unguarded read-modify-write on shared records, CRITICAL −22 in-process-only mutex in multi-instance deployment, HIGH −18 external API call in retry loop without idempotency key, HIGH −16 Redis lock missing compare-and-delete, HIGH −14 idempotency key generated server-side. -
2026-06-19 · CSP · Browser Security · MCP Servers
MCP Server Content Security Policy Deep Dive: Nonce-Based Inline Scripts, strict-dynamic, and report-uri Monitoring for Browser-Based Agent UIs
Browser-based MCP server UIs render tool output that may contain attacker-controlled content — a prompt-injection payload that causes HTML injection sets up XSS with full access to every tool the authenticated session can call. A production-grade CSP closes the XSS surface permanently. This post is the complete playbook: building the baseline from default-src 'none', per-request nonce generation with crypto.randomBytes() (never reused, Cache-Control: no-store to prevent cached-nonce attacks), 'strict-dynamic' trust propagation to eliminate CDN host allowlists, sandboxed iframes for tool output rendering using blob URLs with sandbox="" to prevent script execution and same-origin access, style-src hardening against CSS injection and attribute exfiltration attacks, upgrade-insecure-requests for mixed content, and report-uri violation telemetry with rate-limited collection endpoints. Includes the complete production policy string, CSP mistake grid (unsafe-inline, static nonce, wildcard script-src, missing frame-ancestors, rendering tool output in main document context), deployment checklist, and SkillAudit findings: CRITICAL −24 no CSP on authenticated UI, CRITICAL −22 unsafe-inline in script-src, HIGH −18 static nonce, HIGH −16 missing frame-ancestors, HIGH −14 tool output in main document context.
Read post → -
2026-06-19 · SSRF · Advanced Patterns · MCP Servers
MCP Server SSRF Advanced Patterns: DNS Rebinding Chains, Cloud Metadata Exploitation, IPv6 Bypass, and TOCTOU in URL Validation
Basic SSRF prevention — blocking 127.0.0.1 and 10.0.0.0/8 in a URL allowlist — stopped being sufficient years ago. Four advanced patterns defeat allowlist-only defenses: DNS rebinding (attacker-controlled domain resolves to a public IP at validation time, then re-resolves to 169.254.169.254 at fetch time because TTL=0 forces re-resolution), cloud metadata service exploitation (AWS IMDS v1 at 169.254.169.254 returns IAM role credentials with no authentication — a single SSRF to /latest/meta-data/iam/security-credentials/ yields rotating AWS keys), IPv6 notation bypass (::1, ::ffff:127.0.0.1, ::ffff:7f00:1, fc00::1 all route to loopback or private ranges and bypass IPv4-only blocklists), and the TOCTOU race between dns.resolve() at validation time and the re-resolution that fetch() triggers. Covers the isBlockedIPv4/isBlockedIPv6 CIDR check implementation, the safeFetch() pattern that connects to the resolved IP directly (preventing re-resolution), AWS IMDSv2 and why it doesn't fully eliminate SSRF risk if PUT requests are possible, IPv4-in-IPv6 hexadecimal decoding, and redirect chaining defense (re-validating every redirect destination through the same SSRF check). Complete Node.js implementations of safeResolveUrl() and safeFetchWithRedirects(). SkillAudit findings: CRITICAL −24 fetch() with unvalidated user URL confirmed to reach IMDS, CRITICAL −22 DNS rebinding window open (hostname passed to fetch() for re-resolution), CRITICAL −20 IPv4-only blocklist missing ::1 and ::ffff forms, HIGH −18 redirect following without re-validating destination, HIGH −16 no network-layer SSRF block (iptables / security group), HIGH −14 only first DNS result checked.
Read post → -
2026-06-18 · Supply Chain · npm · MCP Servers
MCP Server Supply Chain Security: npm Lockfile Integrity, Typosquatting Detection, and Provenance Attestation
The most dangerous vulnerability in an MCP server is often in the code you installed, not the code you wrote. A compromised npm dependency — whether via typosquatting, account takeover of a popular package's maintainer, dependency confusion, or a malicious postinstall script — delivers arbitrary code execution inside your MCP server process at install time. This post covers the full npm supply chain attack surface and a six-layer defense: using
Read post →npm cifor lockfile-verified deterministic installs (and whynpm installin CI is insufficient), runningnpm audit --audit-level=highas a required CI gate, detecting typosquat packages via Levenshtein edit-distance checks against a known-legitimate allowlist, verifying npm provenance attestation (Sigstore-backed publish provenance linking each tarball to the specific CI run that produced it), blocking install-time script execution withignore-scriptsor a curated postinstall allowlist, and pinning direct dependencies against the lockfile integrity hash. Includes a complete GitHub Actions workflow, a typosquat-check.js script, a planned dependency update workflow with git-diff lockfile review, and an audit checklist. -
2026-06-18 · Security · Behavioral Detection · MCP Servers
MCP Server Behavioral Intrusion Detection: Building a Session Anomaly Detector from Scratch
Static analysis catches the vulnerabilities baked into MCP server code at rest; a behavioral intrusion detector catches the attacks that unfold at runtime. This post builds a complete session anomaly detector in Node.js: a per-session record tracking call velocity (sliding-window timestamps, not calendar-minute counters), tool sequence ring buffer, privileged-tool set, and anomaly score accumulator. Five scoring rules — velocity (30/60/120 CPM thresholds with +5/+15/+40 deltas), error rate (30%/60% thresholds), first-time privilege escalation (within 5s = +25, after 5 minutes of low-privilege calls = +15), Shannon entropy on argument strings (entropy >4.5 bits/char signals base64 exfiltration encoding = +10), suspicious sequence pairs (readFile→callUrl, readSecret→callUrl = +30). Composite thresholds: log at 10, alert at 40, block and clear session at 80. Includes full implementation of SessionRecord, anomaly-scorer.js, and behavioralIDS middleware. Handler-first ordering rationale: execute then score catches errors as signals; add pre-execution velocity block as the one exception where volume risk outweighs diagnostic value. SkillAudit findings: CRITICAL −20 no session identity, HIGH −16 no tool call logging, HIGH −14 no privilege classification, MEDIUM −10 no rate limiting.
Read post → -
2026-06-18 · Architecture · Zero-Trust · MCP Servers
MCP Server Zero-Trust Architecture: Never Trust, Always Verify at the Tool Call Level
Zero-trust for MCP servers is not about network segmentation — it is about applying the principle at the unit of damage: the individual tool call. Four principles adapted for the MCP threat model: (1) verify identity on every tool call via per-call JWT check + Redis revocation set, not just at session establishment; (2) treat every tool argument as adversarial with two-layer validation (Zod structural + semantic SSRF/path-traversal/injection checks); (3) sanitize every tool response before injecting into LLM context with external-data envelopes, content filtering, and size caps; (4) attenuate scope on every agent delegation via intersected capability tokens with delegation depth limits. Includes Node.js implementations of each principle — withPerCallAuth(), validateFetchArgs() with DNS-resolved IP check, sanitizeToolResult() with injection pattern detection, and delegateScope() with parentJti chain tracking. SkillAudit findings: CRITICAL −24 session-only auth, CRITICAL −22 unvalidated URL arguments, HIGH −16 raw tool responses injected to LLM context, HIGH −18 sub-agent delegation without scope attenuation.
Read post → -
2026-06-18 · Security · HTTP · MCP Servers
MCP Server HTTP Request Smuggling: CL.TE, TE.CL, and CONNECT Tunneling Behind Reverse Proxies
HTTP request smuggling exploits disagreement between a reverse proxy and the origin server about where one HTTP/1.1 request ends and the next begins. For MCP servers deployed behind Caddy, nginx, AWS ALB, or Traefik, the consequence is severe: an attacker who can route requests to the same server can inject tool call requests into other users' active sessions, bypass authentication headers added by the proxy, and hijack SSE streams mid-stream. Covers CL.TE (front-end uses Content-Length, back-end uses Transfer-Encoding), TE.CL (front-end dechunks, back-end stops at Content-Length), TE.TE obfuscation via malformed Transfer-Encoding values, and CONNECT tunneling for proxy bypass. Explains why MCP SSE endpoints amplify the risk: a smuggled request injected during an active SSE session is delivered to the victim's Claude stream as if it came from a legitimate tool execution. Node.js mitigations (reject simultaneous Content-Length and Transfer-Encoding, explicit CONNECT rejection), Caddy configuration (H2 transport to back-end, header_up -Transfer-Encoding), nginx configuration (proxy_http_version 1.1 + proxy_set_header Connection "", OpenResty Lua CL+TE rejection), and end-to-end HTTP/2 as the definitive fix. Proxy-specific quick-reference table for Caddy, nginx, AWS ALB, HAProxy, and Traefik. SkillAudit findings: CRITICAL −24 CL.TE confirmed, CRITICAL −22 TE.CL confirmed, HIGH −18 CONNECT method not rejected, HIGH −16 H1.1 keep-alive to origin without normalisation, HIGH −14 TE.TE obfuscation accepted, MEDIUM −8 no H2 support on back-end listener.
Read post → -
2026-06-18 · Security · Secrets Management · MCP Servers
MCP Server Secrets Rotation Without Downtime: Dual-Key Overlap, AWSCURRENT/AWSPREVIOUS Patterns, and In-Process SIGHUP Reload
Rotating secrets in a continuously-running MCP server is uniquely hard: the server can't restart to pick up new credentials without dropping every active Claude session, and a rotation window where the old key is revoked before the new one is distributed causes live tool call failures. This post covers four patterns: dual-key overlap for external API keys (issue new key → distribute → revoke old after TTL), AWSCURRENT/AWSPREVIOUS fallback for AWS Secrets Manager (fallback to AWSPREVIOUS on 401 during rotation window), SIGHUP-based credential cache invalidation (lazy TTL cache + process.on('SIGHUP') handler avoids process restart), and JWKS kid rotation for JWT signing keys (add new kid → wait for cache propagation → start signing with new kid → wait for max token TTL → remove old kid). SkillAudit findings: CRITICAL −22 naive rotate-then-distribute causes live auth failures, HIGH −15 credentials cached in module scope with no reload mechanism, HIGH −12 database connection pool with stale credentials after rotation, HIGH −10 JWT JWKS rotation without overlap window.
Read post → -
2026-06-18 · Security · SSTI · MCP Servers
MCP Server SSTI Deep Dive: Handlebars Sandbox Escapes, Nunjucks Template Injection, and EJS RCE in LLM Tool Handlers
Server-side template injection in MCP tool handlers is uniquely dangerous: the "user" providing the payload is often the LLM itself, manipulated by attacker-controlled content in tool results. A document the agent reads or a database row it queries can contain a Handlebars constructor chain escape or an EJS outputFunctionName RCE payload — and if the tool handler renders that content as a template, the attacker achieves RCE without ever talking to your server directly. This post covers all three template engine families (Handlebars, Nunjucks, EJS), their specific escape paths, why the Handlebars sandbox fails, how Nunjucks reaches process.mainModule, and the EJS outputFunctionName trick. SkillAudit findings: CRITICAL −25 Handlebars.compile() on user-supplied string (constructor chain escape), CRITICAL −24 Nunjucks nunjucksEnv.renderString() on tool result (process.mainModule.require chain), CRITICAL −23 EJS ejs.render() with user-supplied template (outputFunctionName RCE), HIGH −16 no template allowlist, HIGH −14 no sandbox configuration, MEDIUM −8 template compilation at request time. The fix for all three engines is the same: never compile or render user-supplied strings as templates — compile from trusted static sources at startup, pass dynamic values as data context only.
Read post → -
2026-06-15 · Security · gRPC · MCP Servers
MCP Server gRPC Transport Security: TLS Configuration, Deadline Propagation, Metadata Auth, and Streaming Authorization
MCP servers that use gRPC as their transport layer or call upstream gRPC services face four distinct attack classes that REST servers don't: insecure channel credentials (createInsecure() leaves all traffic unencrypted and unauthenticated), missing deadline propagation (upstream gRPC calls run indefinitely after the MCP client disconnects), metadata credential leakage (logging all gRPC metadata exposes Authorization headers; blind metadata forwarding amplifies token scope across services), and streaming authorization drift (auth checked only at stream open — revoked credentials keep receiving streamed data until the stream closes). Covers Node.js @grpc/grpc-js patterns: one-way TLS and mTLS with combineChannelCredentials, deadline extraction from incoming gRPC context and propagation to outgoing calls, sanitizing interceptors that redact sensitive metadata keys, allowlist-based metadata forwarding, and periodic re-validation inside streaming handlers using Redis revocation sets. Control matrix: six controls × attack class, root cause, control, library, SkillAudit axis. SkillAudit findings: CRITICAL −24 insecure channel to internal gRPC service, CRITICAL −20 no deadline propagation, HIGH −16 full metadata logging, HIGH −14 blind metadata forwarding, HIGH −12 no re-validation in streaming handlers, MEDIUM −8 server reflection enabled in production.
Read post → -
2026-06-15 · Security · GraphQL · MCP Servers
MCP Server GraphQL Security: Introspection Abuse, Batch Query DoS, Field-Level Authorization Bypasses, and Query Complexity
GraphQL MCP servers expose a wider attack surface than REST: introspection reveals the full schema to any caller in a single query, unbounded depth enables recursive DoS, aliases allow batching hundreds of operations in one HTTP request bypassing per-request rate limits, and field-level authorization must be enforced in every resolver — not just the root query that first surfaces a type. This post covers all four attack classes with Node.js defenses. SkillAudit scan of 400+ MCP servers found 62% with introspection enabled in production, 71% with no query depth limit, 54% with no complexity budget, and 38% with field-level authorization gaps. Implementations for NoSchemaIntrospectionCustomRule (blocks all introspection including __type), graphql-depth-limit (depthLimit:7 rejects recursive queries before execution), graphql-query-complexity (maximumComplexity:1000 with per-field cost annotations for list joins), graphql-armor alias limits (maxAliases:15 closes batch bypass), graphql-shield per-field rules (canReadApiKeys fires regardless of which query path reaches the User type), and custom formatError stripping stack traces and internal error details. Control matrix table: seven controls × attack class, root cause, library, and SkillAudit axis. SkillAudit findings: CRITICAL −25 introspection enabled in production, CRITICAL −22 no depth limit, HIGH −18 no complexity limit, HIGH −16 no alias limit, HIGH −15 field-level auth gaps, MEDIUM −10 field suggestions enabled, MEDIUM −8 internal error details in extensions, LOW −4 no complexity logging.
Read post → -
2026-06-16 · Security · Sessions · Authentication
MCP Server Session Fixation and Hijacking: Stateful Session Attacks in Long-Lived LLM Agent Contexts
Stateful MCP servers that issue session IDs to track authenticated agent contexts are vulnerable to session fixation (attacker pre-sets a session ID before authentication; if the server does not regenerate it on login, the attacker's known ID becomes an authenticated session) and session hijacking (stealing an authenticated token via network interception over plain HTTP, XSS in a companion web UI, or predictable token generation). Long-lived LLM agent sessions make these attacks worse: a hijacked session may give an attacker hours of autonomous agent actions under legitimate credentials with no human checking for anomalous behavior. Covers three attack scenarios with Node.js code: pre-auth session fixation via saveUninitialized: true and how session.regenerate() breaks the attack, token theft over plaintext HTTP transport with TLS enforcement and HttpOnly/Secure cookie patterns, and concurrent agent session race conditions with Redis WATCH/MULTI and agent-bound HMAC tokens. Session ID generation: why crypto.randomBytes(32).toString('hex') is the only safe approach and why UUID v1, Math.random(), and timestamp-based IDs are predictable. Six-row comparison table covering fixation, hijacking, token interception, predictable IDs, concurrent sessions, and session timeout. SkillAudit grade impacts: CRITICAL −25 (no session regeneration after auth), CRITICAL −22 (tokens over plain HTTP), HIGH −15 (no session expiry), HIGH −12 (predictable session IDs), HIGH −10 (concurrent agent sessions sharing mutable state), MEDIUM −6 (no invalidation on agent context reset), MEDIUM −4 (missing Secure/HttpOnly flags on session cookies).
Read post → -
2026-06-15 · Security · Caching · Multi-Agent
MCP Server Cache Poisoning: How LLM Agents Can Poison Shared Caches to Corrupt Other Sessions
When multiple LLM agent sessions share a Redis or in-memory cache keyed by tool name and arguments, a malicious prompt injection can pre-populate cache keys with adversarial responses that any future session reads as legitimate tool output. This post covers three attack classes: predictable key pre-population (attacker controls the first fetch of a URL that gets cached, poisoning all subsequent sessions), cache stampede injection (race the repopulation window after cache invalidation to insert malicious content), and cross-session state injection via shared writable cache tools (prompt injection calls set_note with attacker-controlled values that other sessions read as policy). Why LLM agents are uniquely vulnerable: no result provenance tracking, instruction-following from tool output, and multi-session fan-out from a single poisoning event. Mitigations with code: per-session namespace isolation (prefix all cache keys with session ID to break the shared key space), HMAC-signed cache values (timingSafeEqual verification, reject unsigned entries as cache misses), short TTLs (≤5 minutes for agent-influenced values), strict namespace separation between agent-readable policy keys and agent-writable session keys, and cache provenance metadata in tool results. Production checklist with seven controls. SkillAudit grade impacts from CRITICAL −25 (shared writable cache, no session isolation) to MEDIUM −4 (no stale-while-revalidate for long-TTL entries).
Read post → -
2026-06-14 · Security · Sandbox · Systems
MCP Server Runtime Sandbox Design: Isolating Tool Execution with vm.runInContext, Worker Threads, and Seccomp
MCP tool handlers run code paths shaped by LLM-generated inputs and perform privileged operations — file reads, HTTP fetches, database queries — inside a shared server process. Without isolation, a single prompt injection that redirects a tool handler reaches the filesystem, environment variables, and credentials of the entire process. This post covers three isolation layers that compose to contain the blast radius: vm.runInContext for V8-context sandboxing (separate global object with no prototype chain connection to the host context, CPU timeout to block infinite-loop event-loop starvation, stripped context that excludes require/process/global), Worker threads for event-loop and heap isolation (separate V8 isolate with a separate heap, resourceLimits.maxOldGenerationSizeMb to cap memory per worker, hard terminate on timeout, worker pool for latency-sensitive servers), and kernel-level containment with Node.js 22 --permission flags (--allow-fs-read/write allowlists, network blocking, no child process spawning) and seccomp-bpf Docker profiles (SCMP_ACT_ERRNO for execve, ptrace, mount — blocking the syscalls needed for privilege escalation). Comparison table across six isolation dimensions: heap isolation, filesystem isolation, network isolation, subprocess spawning, overhead, and complexity. Threat-model guide for choosing the right layer: vm for pure transformations (~0ms overhead), Worker+vm for I/O-bound execution (10–20ms), subprocess+permissions for user-authored code (20–100ms). Four common misconfigurations with code: passing require or process into the vm context, omitting the timeout, accepting non-string code input, and not calling worker.terminate() on timeout. SkillAudit grade impacts from CRITICAL −25 (eval with no sandbox) to MEDIUM −5 (sandbox context includes fetch).
Read post → -
2026-06-14 · Security · WebSocket · Networking
MCP Server WebSocket Security: Authentication, Message Framing Attacks, and Connection Lifecycle
WebSocket-based MCP servers give up the per-request stateless model that HTTP security is built on — there is no CORS preflight, no per-request auth header, and no request-scoped rate limiting. A single upgrade handshake opens a long-lived channel that stays open for hours while an LLM agent makes dozens of tool calls. Covers the complete attack surface: cross-site WebSocket hijacking (CSWSH — cookies are sent on the WebSocket upgrade so a browser page at attacker.com can open a full bidirectional channel using the victim's credentials), upgrade-time authentication (the correct pattern validates the JWT before calling handleUpgrade(), not in a first-message auth phase that leaves the connection open before identity is established), three message framing attack classes (ping flood exploiting the RFC 6455 requirement to auto-respond to every Ping, message fragmentation-based size bypass with the ws library's default 100 MB maxPayload, and control frame injection via proxy desync), connection lifetime auth drift (JWT expires mid-session but the WebSocket stays open), per-identity rate limiting that spans reconnects (reconnect cycling bypasses per-connection limits), and secure close sequences (application codes 4001–4004 for auth/session events, no error details in close reason string). Seven-step security checklist with code for each. SkillAudit grade impact table: no upgrade-time auth CRITICAL −20, no Origin validation HIGH −12, default maxPayload HIGH −10, no connection TTL HIGH −8, per-connection rate limit only MEDIUM −6, no ping rate limiting MEDIUM −5, error details in close reason MEDIUM −5.
Read post → -
2026-06-16 · Security · Architecture · Authorization
MCP Server Authorization Models Compared: Capability-Based vs. Role-Based vs. Policy-Based for LLM Agents
RBAC grants a role and that role's permissions apply to everything in the session — including every tool call an LLM agent makes autonomously. This breaks silently under agentic use because agents compose tools in ways no human anticipated, hold ambient authority for the entire session, and cannot be interrupted when a prompt injection redirects their goal. Compares three authorization models for MCP servers: capability-based tokens (narrow scope at task issuance, UCAN delegation for sub-agents, short TTL, explicit revocation — the fix for ambient authority), role-based RBAC (fast and auditable for simple single-tenant servers with trusted human callers, broken for multi-step agentic sessions), and policy-based OPA/Cedar (cross-call session-state rules, business-hours constraints, chain detection — earns its complexity cost only at enterprise scale). Includes working Node.js implementations for all three, a seven-row comparison table covering ambient authority risk, cross-call rule support, delegation, implementation cost, and prompt injection resistance, and a SkillAudit Permissions axis grade impact table. The minimum viable capability implementation takes 30 minutes to add to an existing RBAC server.
Read post → -
2026-06-15 · Engineering · Supply Chain · Security
MCP Server Supply Chain Risk: How a Compromised npm Dependency Becomes a Compromised Tool Handler
A single malicious package in your MCP server's dependency tree can silently exfiltrate credentials, tamper with tool responses, or phone home on every tool call — all without touching your own code. Covers why MCP servers are a high-value supply chain target (elevated credentials, tool argument visibility, no egress filtering), a worked example showing how a compromised transitive dependency (fast-str four levels deep) exfiltrates every credential-pattern environment variable on a 60-second interval, three attack vectors specific to MCP servers (process.env credential scanning, tool argument interception and response tampering, dependency confusion via unscoped internal package names), the four controls that stop supply chain attacks (npm ci lockfile-strict, lockfile hash verification in CI, npm audit exit-code enforcement, provenance attestation for direct dependencies), a complete GitHub Actions workflow enforcing all four, runtime egress monitoring via https.request intercept to detect compromised dependency phone-home, dependency tree assessment commands, SBOM generation with CycloneDX, and a grade impact table mapping each supply chain gap to a SkillAudit finding and grade delta.
Read post → -
2026-06-14 · Engineering · Observability · Security
MCP Server Security Monitoring and Alerting: What to Alert On, Threshold Calibration, and How to Avoid Alert Fatigue
A practical framework for monitoring MCP servers for security events in production: four alert categories (authentication failures, anomalous tool call patterns, data volume and exfiltration signals, configuration and filesystem tampering), threshold calibration from baseline traffic (not from a blog post), alert routing by severity tier (P0 pages on-call in 15 minutes, P1 alerts team channel within 4 hours, P2 batches to daily digest), SIEM integration for cross-server correlation and retrospective investigation, append-only log forwarding that survives incident tampering, and the three most common monitoring mistakes (logging only in error handlers, including credential values in logs, alerting on every anomaly equally). Includes the minimum viable monitoring setup (one security logger, two events, one alert rule, one external sink) that takes 2–4 hours to implement and surfaces real security signals within the first week. SkillAudit grade impact table mapping each observability gap to a finding severity and grade delta.
Read post → -
2026-06-13 · Security · Attack Patterns · Authorization
MCP Server Tool Chaining Attacks: Read-to-Write Privilege Escalation via Chained Tool Calls
Three concrete attack chains showing how an attacker with only read-only MCP tool access escalates to full write access or RCE — without touching a single exploit. Covers env-var extraction to API takeover (read_file → .env → fetch_url with Stripe key), contact enumeration to mass PII exfiltration (list_contacts × 1000 → send_message to attacker), and database schema discovery to shell execution (query schema → write_file malicious script → UPDATE cron_jobs). Defenses: tool category composition guards (retrieval/mutation/external), session-level aggregate rate limits (max 5 retrievals before external call), write-intent parameters that break automated chain construction, executable path allowlisting for filesystem write tools, and per-session audit log with chain detection. Includes grade impact table mapping each structural pattern to a SkillAudit finding and grade delta.
Read post → -
2026-06-13 · Engineering · Testing · Security
MCP Server Security Testing with Vitest: Unit Tests for Auth, Input Validation, and Error Handling
A practical guide to writing Vitest unit tests that verify the security properties of your MCP server — not just functional correctness. Covers four test suites: auth bypass tests (missing token, expired token, IDOR, and DB short-circuit verification), input validation edge cases (path traversal, null bytes, oversized inputs, and a parameterized adversarial battery), error information leakage tests (FORBIDDEN_LEAK_PATTERNS helper that checks every error path for stack traces, internal paths, and DB error strings), and rate limiter per-caller isolation tests. Includes a GitHub Actions workflow with coverage thresholds on auth and error-handling files, and a grade impact table mapping each test category to the SkillAudit finding it covers.
Read post → -
2026-06-13 · Engineering · Error Handling · Security
MCP Server Error Handling: What to Return When Something Goes Wrong
A complete engineering guide to the four error categories every MCP server must handle — input validation, authorization, downstream service errors, and unexpected panics — with safe response patterns for each. Covers why raw error messages and stack traces earn HIGH findings, how to write a thin ToolError abstraction that keeps internals out of responses, why authorization and not-found errors should look identical to prevent resource enumeration, and how to log errors with argsHash correlation without leaking credential values. Includes grade impact table and a three-file setup you can copy into any MCP server.
Read post → -
2026-06-13 · Tutorial · Architecture · Security-First
Building a SkillAudit-Ready MCP Server From Scratch: Security-First Architecture Walkthrough
A complete step-by-step tutorial for building an MCP server that achieves and maintains an A grade. Covers all six audit axes with working Node.js code: startup config validation with Zod to reject placeholders and misconfiguration, per-call authentication with constant-time comparison, structured audit logging with argsHash for correlation without credential exposure, safe error abstraction that scrubs stack traces from callers, strict allow-list input schemas, rate limiting with per-tool per-caller windows, and a CI gate (GitHub Action) that blocks grade regressions from shipping. Each section explains why the pattern earns its score, not just what to copy.
Read post → -
2026-06-13 · Incident Response · Case Study · Path Traversal
MCP Server Zero-Day: A 6-Hour Incident Timeline and What We Learned
A detailed 6-hour incident timeline: how a path traversal vulnerability in a popular MCP server was exploited, discovered, and patched — from first anomaly alert to coordinated disclosure. The vulnerability had been flagged as HIGH by SkillAudit 14 days before exploitation. Covers triage, scope assessment, credential rotation, patch development, coordinated disclosure, and five lessons every MCP server maintainer should take: input validation in tool parameters, actionable scan finding alerting, anomaly detection value, credential scope, and emergency disclosure timelines.
Read post → -
2026-06-12 · Security · Checklist · Pre-deployment
MCP Server Security Audit Checklist: The 15-Point Pre-Deployment Review
A practical 15-point security checklist for MCP server developers covering authentication, input validation, secrets handling, logging, and transport security — with explicit pass/fail criteria for each control. Covers API key validation, per-tool authorization, token expiry enforcement, confirmation gates for write tools, schema validation, shell and path injection prevention, prompt injection defense, secrets hygiene, audit logging, error message exposure, and TLS enforcement. A checklist run takes 45–60 minutes; SkillAudit automates 11 of the 15 controls on every push.
Read post → -
2026-06-12 · Security · Agentic AI · Architecture
The Ambient Authority Problem in MCP: Why Session-Level Auth Isn't Enough for Agentic AI
Ambient authority lets any tool in an MCP server act with the full power of the session token — regardless of what the user intended. A single prompt injection exploiting ambient authority is a session-wide compromise, not just a single-tool compromise. Covers the attack model, per-tool capability scoping as the solution, orchestrator-side token issuance, argument injection defense, and a migration path from session-level to capability-based auth.
Read post → -
2026-06-12 · Compliance · Financial Services
MCP Server Security for Financial Services: PCI-DSS, Cardholder Data, and Agentic AI Tool Access to Payment APIs
When AI agents use MCP servers to call Stripe, Plaid, or internal banking APIs, they bring the agentic layer into PCI-DSS scope. Covers CDE boundary definition, scope classification for common MCP patterns, the seven most-impacted PCI v4.0 requirements (Req 3/4/6/7/8/10/11), CHD log redaction implementation, per-invocation audit trail structure, network segmentation architecture, service account discipline for Req 8, prompt injection as a payment fraud vector, and how to frame MCP servers in a QSA assessment.
Read post → -
2026-06-14 · Compliance · Healthcare
MCP Server Security for Healthcare: HIPAA, PHI Protection, and Agentic AI Tool Access
When AI agents use MCP servers to query EHR APIs or FHIR endpoints, HIPAA's Technical Safeguards apply to the MCP server layer. Covers Business Associate obligations, 45 CFR 164.312 audit logging requirements, minimum necessary access design patterns, per-call authentication, encryption requirements, and breach notification triggers for MCP tool call data containing PHI.
Read post → -
2026-06-13 · Security Operations
The MCP Server Security Review Checklist: 50 Questions for Teams
A 50-question security review checklist for MCP servers organized into 8 domains: authentication, authorization, input validation, network security, secrets management, supply chain integrity, observability, and incident response. Includes severity tiers (Blocker/Major/Minor), the precise evidence to look for in source code, and a scoring summary table for team review meetings.
Read post → -
2026-06-12 · Authentication Security
JWT algorithm confusion attacks on MCP servers: RS256→HS256, alg:none, and weak HMAC secrets
JWT algorithm confusion (CVSSv3 9.8) lets an attacker forge a valid-looking token using only the server's public key. A SkillAudit scan of 400+ MCP servers found 14% vulnerable to at least one pattern: RS256→HS256 confusion (attacker signs with HS256 using public key bytes as the HMAC secret), alg:none bypass (unsigned tokens accepted), and weak HMAC secrets (crackable offline in seconds). Includes the exact one-line fix for each pattern and how SkillAudit detects them via tree-sitter static analysis.
Read post → -
2026-06-11 · Security Architecture
MCP server secrets management: Vault, AWS Secrets Manager, and the .env anti-pattern
61% of community MCP servers store credentials in .env files; 18% have at least one committed to git history. This guide covers the five exposure vectors of .env secrets, the runtime fetch pattern with AWS Secrets Manager and HashiCorp Vault, secret rotation without server restart using a TTL cache, and the per-request audit trail that makes secret access auditable — with WRONG/RIGHT Node.js patterns for each.
Read post → -
2026-06-11 · Security Architecture
MCP server sandboxing: running untrusted tool code in isolated processes
Three isolation layers for MCP servers that execute community plugins or user-supplied code: the Node.js vm module (JavaScript context boundary), Worker threads (separate V8 isolate), and Docker sidecars (OS-level namespace isolation). Includes a comparison table of what each layer blocks — filesystem access, network connections, prototype pollution, fork bombs, supply chain — and a decision guide for choosing the right layer for your threat model.
Read post → -
2026-06-11 · Developer Guide
MCP server observability: what to log, what not to log, and how to use logs for security detection
A complete guide to structured logging for MCP servers: the four event categories every server must emit, the no-log list (argument values, response bodies, credentials), and the eight detection rules that turn your log stream into a real-time security sensor.
Read post → -
2026-06-12 · Open-Source Guide
MCP server security for open-source maintainers: what reviewers check in 2026
The Anthropic Skills Directory review process now requires a security review before listing. This guide covers what reviewers actually check (six axes, automated scan + human review), why servers get rejected, the SECURITY.md and CONTRIBUTING.md templates that prevent 80% of rejections, and a pre-submission self-assessment checklist ordered by rejection risk.
Read the post → -
2026-06-11 · Developer Guide
How to harden an existing MCP server without breaking integrations
A six-phase additive hardening path for live MCP servers — observe, warn-only input validation, soft rate limiting, shadow authentication, command injection hardening, and permission scoping — each phase with an enforcement gate you flip only after verifying zero legitimate triggers in your warn-only logs. No surprise breaks for existing callers.
Read the post → -
2026-06-10 · DevSecOps Guide
MCP server security for DevSecOps: integrating SkillAudit into CI/CD pipelines
Shift security left: wire SkillAudit grade-gates into GitHub Actions, GitLab CI, and pre-commit hooks so insecure MCP servers never reach the registry. Complete workflow YAML, fail-open vs fail-closed strategies, axis-level policy gating, SBOM export for SOC 2, and an exemption workflow that doesn't become a rubber-stamp.
Read the post → -
2026-06-10 · Developer Guide
MCP server input validation: beyond Zod — custom validators, allow-lists, and adversarial LLM inputs
Zod validates shape and type, but not semantic safety. A filename that parses as a valid string can still be
Read the post →../../etc/passwd; a URL that passes the schema check can still resolve to an internal metadata endpoint. This guide covers the four layers of input validation every MCP tool handler needs: schema parsing, semantic allow-listing (path traversal, SSRF, command injection), policy context, and output validation — with complete Node.js implementations and a full validated handler pattern. -
2026-06-10 · Developer Guide
MCP server rate limiting deep dive: sliding window, token bucket, and adaptive throttling
Rate limiting is a security control, not just a reliability control. In the MCP context, a misbehaving or compromised LLM can call your tool in a tight loop, burn through API credits, or exfiltrate data at a rate that bypasses anomaly detection. This deep dive covers three production-ready algorithms — sliding window (most accurate), token bucket (burst-friendly), and adaptive throttling (load-aware) — with complete Node.js implementations, memory profiles, when to use each, and how SkillAudit grades rate limiting hygiene.
Read the post → -
2026-06-10 · Developer Guide
When to reject a tool call vs return an error: defensive MCP handler design
The MCP spec gives you two ways to signal failure: throw an exception or return
Read the post →isError: true. Both signal failure, but the receiver is different — one goes to the client layer, one goes directly into the LLM's context. Choosing the wrong one creates retry loops, leaks internal state, or silently swallows security violations. This post gives you the decision rules, a decision table covering every common failure case, and six detailed scenarios: auth failures, input validation, downstream errors, policy violations, timeouts, and suspected prompt injection. -
2026-06-10 · Developer Guide
The top 10 MCP security mistakes developers make in their first server
The ten security mistakes that appear most often in first-time MCP servers — with the exact failing code pattern and the minimal fix for each. Hardcoded credential fallbacks, shell: true with user input, console.log left in production, missing path resolution guards, overly broad tool permissions, no rate limiting on expensive tools, verbose error messages returned to the LLM, prompt injection pass-through from external content, global state shared across sessions, and unauthenticated HTTP transport. Four Critical, four High, two Medium — and a fix effort of under 4 hours total across all ten.
Read the post → -
2026-06-09 · Research Report
The MCP server security debt report: 30 days of scanning 500 community servers
We scanned 500 community MCP servers over 30 days. 36.7% had SSRF vulnerabilities. 43% had unsafe command-exec paths. 61% logged credentials in plaintext. This report breaks down the grade distribution across the corpus, the most common vulnerability categories by frequency and severity, security debt quantification per tier, the maintenance debt dimension, patterns in the highest-debt servers, and what the re-scan data shows about whether remediation actually sticks.
Read the post → -
2026-06-07 · Developer Guide
How to write a SkillAudit-ready SECURITY.md for your MCP server
A SECURITY.md file is one of the highest-leverage, lowest-effort improvements you can make before publishing an MCP server. This guide explains section by section what the SkillAudit scanner checks — Scope, Credentials, Vulnerability Reporting, Logging, Known Limitations, and Audit History — with the point values, the common mistakes that drop your grade, a full copy-paste template, and a minimum viable SECURITY.md for when you need to pass the gate quickly.
Read the post → -
2026-06-06 · Security Leadership
MCP server security for CISOs: executive briefing on LLM tool chain risk
MCP servers are the new shadow IT: they run on engineer laptops, hold production credentials, and execute code, yet most organizations approve them with no more scrutiny than a browser extension. This briefing covers the full threat model (supply chain, prompt injection, misconfiguration), a realistic incident walkthrough, how SkillAudit grades map to board-level risk tiers, the five controls that define a mature MCP security program, and a three-sentence board summary you can drop into your next risk review.
Read the post → -
2026-06-07 · Product Management
MCP server security for product managers: translating SkillAudit grades into business risk
Your team wants to ship faster by adding new MCP servers. Your security team is worried. This guide gives product managers the vocabulary to translate A–F SkillAudit sub-scores into business risk language, communicate findings to leadership and legal, and build a lightweight four-step intake process that evaluates new servers without creating a security bottleneck. Covers the sub-score override rule, common PM mistakes, and when to involve legal.
Read the post → -
2026-06-06 · Procurement & Governance
MCP server vendor security questionnaire: what to ask before approving internal adoption
Community MCP servers are typically evaluated with a GitHub star count and a README skim. This post gives procurement teams a 15-question security questionnaire covering SSRF, credential scope, prompt injection, dependency practices, and incident response — with the answers that should block adoption, how SkillAudit grades map to procurement risk tiers, a CI gate configuration for minimum grade enforcement, and a sign-off template for internal audit trails.
Read the post → -
2026-06-05 · Remediation
From C to A grade: a week-by-week MCP server remediation plan
A C grade is not a rejection — it is a prioritized work order. This post turns the SkillAudit report into a concrete four-week remediation plan: week 1 fixes Critical and High security findings (SSRF, injection), week 2 reduces permission scopes to minimum, week 3 removes credential logging and hardcoded fallbacks, week 4 commits the lock file and adds a SECURITY.md. Includes expected sub-score progression and the 30-day arc from C (60) to A (88).
Read the post → -
2026-06-05 · Security Architecture
The MCP server supply chain: trust boundaries from tool call to upstream API
Every MCP server sits at the center of a five-layer dependency graph. The attack surface that gets exploited spans all five: the LLM prompt boundary where adversarial context steers tool argument generation, the argument trust boundary where server code must validate LLM-supplied input as untrusted, the server code internals covering credential handling and logging, the npm dependency layer with ambient access to process.env and the network, and the upstream API credential scope and response content that can carry secondary prompt injection. Maps what SkillAudit checks at each layer and what a complete supply chain audit actually requires.
Read the post → -
2026-06-05 · Policy & Governance
How to write an MCP server security policy for your organization
A template security policy for organizations adopting MCP servers internally. Covers grade thresholds by environment (A for production PII, B for internal data, C for dev), a GitHub Action CI gate that enforces minimum grades and blocks F sub-scores, the vendor assessment checklist for new adoptions, the exception workflow (60-day expiry, manager + security sign-off, stored artifact required), re-audit triggers beyond the 90-day cadence, and a condensed plain-text policy block you can drop into your internal wiki.
Read the post → -
2026-06-05 · Compliance
MCP server audit trail design for SOC 2 and GDPR compliance
MCP servers that touch personal data or operate under SOC 2 scope need structured, tamper-evident audit logs. This post covers the minimum viable audit log schema (event_id, timestamp, session_id, user_id, tool_name, input_summary, outcome, data_classes, credential_ref), how to sanitize input_summary to avoid logging credentials or PII in plaintext, how to implement a SHA-256 hash chain for tamper-evidence, the SOC 2 criteria mapped to specific fields (CC6.1 logical access, CC7.2 monitoring, CC7.4 incident response), GDPR requirements (Article 30 RoPA, Article 15/20 Subject Access Requests, Article 17 right to erasure with the two-table architecture), a tiered retention scheme (90-day hot with PII, 12-month warm without PII, 7-year incident archive), and a checklist for PR review before deploying any MCP server that touches production data.
Read the post → -
2026-06-05 · Resilience Engineering
Designing for resiliency: how to build MCP servers that fail securely
Failure in an MCP server is not just an uptime problem — it is a security event. Without deliberate failure design, partial state, ambient credentials, and exploitable retry paths become the attack surface. This post covers eight patterns that turn failure into a security property: per-call timeout budgets with AbortController, circuit breakers that fast-fail on open upstreams, exponential backoff with full jitter to prevent retry storms, fail-closed authorization checks, idempotency keys for mutating tools, error message hygiene to prevent information disclosure via stack traces, graceful degradation with Promise.allSettled for multi-source tools, and connection pool limits with concurrent-call gates.
Read the post → -
2026-06-04 · Security Methodology
The SkillAudit scorecard explained: how we grade MCP server security across six axes
A complete breakdown of every check we run, how findings map to severity levels, how axis scores are combined into a letter grade, and what you need to fix to move up. Covers the weights for all six axes (Security 35%, Credentials 25%, Permissions 15%, Maintenance 12%, Compatibility 8%, Documentation 5%), the HIGH/MEDIUM/LOW/INFO severity tiers with point deductions, the A–F letter grade thresholds, a worked example showing how a single path traversal finding drops a server from A to B, and what an A grade actually requires in practice.
Read the post → -
2026-06-04 · Incident Response
MCP server security incident response playbook — what to do in the first 60 minutes
When a deployed MCP server has a confirmed security incident, the first sixty minutes determine whether you contain the breach or let it compound. This step-by-step playbook covers all six phases: confirming the incident and scoping the credential set (0–5 min), isolating the server and fencing credentials (5–15 min), rotating every long-lived credential without causing a cascading outage (15–30 min), preserving the audit log with a SHA-256 hash before log rotation (30–45 min), triaging what data was accessed and identifying the entry point (45–55 min), and communicating to vendors, stakeholders, and users (55–60 min). Also covers return-to-service validation and how SkillAudit's audit log history view supports both incident triage and post-incident verification.
Read the post → -
2026-06-04 · Security Analytics
SkillAudit grade drift: how MCP server security scores change over time
A SkillAudit score is not a permanent seal of approval. Analysis of 30-day rescan data shows that Maintenance and Dependency axes regress in 87% and 74% of servers respectively — driven by time and the external advisory ecosystem, not code changes. Security and Permissions hygiene axes improve after authors read their first report. This post covers drift velocity by axis, the badge staleness problem, rescan cadence recommendations, and how to set a CI minimum-grade gate that accounts for drift rather than treating the point-in-time scan as a permanent approval.
Read the post → -
2026-06-04 · Security Architecture
The minimal-footprint MCP server: building for security from the ground up
Most MCP security problems are architectural, not code-level — they stem from decisions made in the first hour. This guide covers six principles that collectively produce A-grade security from the first commit: stdio-only transport (no network attack surface), zero external dependencies (no supply-chain CVE exposure), per-tool credential isolation (blast radius bounded at the tool boundary), no shell invocation (no eval() or exec() on arguments), a declarative permission manifest (machine-readable blast-radius declaration), and an immutable append-only audit log. Includes a 60-line template you can drop into any new MCP server project.
Read the post → -
2026-06-04 · Security Methodology
Why MCP server security scanning is different from code scanning
Semgrep finds exec(userInput). It does not find the tool description that makes an LLM call exec() on untrusted input. This post maps the five gaps between traditional SAST and MCP-specific security scanning — prompt injection via tool descriptions, capability pairing amplification, trust boundary violations, context-window exfiltration, and maintenance drift — with a side-by-side coverage table showing what SAST catches, what MCP-specific scanning catches, and what falls through both.
Read the post → -
2026-06-03 · Security Architecture
Threat modeling an MCP server from scratch: the STRIDE approach
Most MCP servers ship without a threat model. STRIDE — Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege — gives you a structured framework to enumerate attack classes before writing a line of code. This post applies each STRIDE letter to the three MCP trust boundaries (caller→server, server→backend, tool description→model), with a concrete attack scenario, real mitigation code, and SkillAudit check name for each. Ends with a 30-minute threat model exercise you can run on any MCP server today.
Read the post → -
2026-06-03 · Security Testing
Property-based fuzzing for MCP server security testing
Unit tests verify the cases you thought of. Property-based fuzzing generates thousands of adversarial inputs automatically — path traversal strings, null bytes, Unicode bypass variants, boundary integers — and breaks your tool handlers before attackers do. Uses fast-check (Node.js) and Hypothesis (Python) to express four security properties: path containment, no exception leakage, numeric bounds, and Unicode blocklist bypass. Includes CI integration with fixed seeds, the shrinking advantage for minimal failing cases, and a ready-to-drop 30-line template for any MCP server project.
Read the post → -
2026-06-03 · Security Research
Anatomy of a prompt injection attack on an MCP server — kill chain trace
A step-by-step kill chain trace from planted document to exfiltrated secrets: how an attacker embeds a malicious instruction in a workspace file, waits for the user to ask the LLM to summarize it, and uses the LLM's own tool calls to read credentials and exfiltrate them via a webhook — without the user seeing any indication. Covers why correct path checks and HTTPS validation don't stop it, six defenses that actually work (domain allowlists, sensitive-file exclusions, trust tagging, capability separation, user confirmation gates, audit logging), and what SkillAudit's red-team check looks for.
Read the post → -
2026-06-03 · Security Research
The ten most common SkillAudit C grades — and what they share
After auditing hundreds of MCP servers, ten finding patterns account for most C grades: argument logging leaking credentials, over-declared permissions, unvalidated URL schemes, stack trace disclosure, implicit env var reads, shell:true with user-controlled args, unchecked numeric bounds, unsandboxed file paths, unaddressed medium advisories, and stale maintenance signals. All ten share one root assumption: that the caller is always trustworthy. Includes pre-screen checklist and the B-grade path for each finding.
Read the post → -
2026-06-03 · Security Architecture
Building a multi-agent MCP pipeline that doesn't trust itself: security isolation between agents
Identity verification stops impersonation — it does nothing against a compromised orchestrator that sends verified instructions to its workers. This post covers the three-layer model for multi-agent MCP pipeline security: privilege isolation by agent role (orchestrator vs. worker), command allowlists on cross-agent tools (no
Read the post →run_commandsurfaces), and confirmation gates on irreversible operations. Includes the threat model table showing what each compromised agent can do with and without the three layers applied. -
2026-06-03 · DevOps
MCP server security CI/CD pipeline: a complete build pipeline audit checklist
Most MCP servers ship without a single automated security check in CI. This post builds the complete pipeline: pre-commit hooks with ESLint and semgrep, a SkillAudit grade gate in your GitHub Actions PR workflow, lockfile enforcement with npm ci, a shell script that validates declared permissions against actual API usage in source, and branch protection settings that make a security regression impossible to merge. Includes the full combined GitHub Actions YAML and a minimum-viable vs. full-pipeline comparison table.
Read the post → -
2026-06-02 · Deep Dive
The ambient token problem: how LLM-controlled credential selection enables silent exfiltration
When multiple credentials are in scope for an MCP server, the model — not the code — selects which one to use. A prompt injection instruction can direct that selection to an attacker endpoint. Three real scenarios (credential-name argument, credential-store tool, credentials in descriptions), the complete exfiltration kill chain, why static analysis misses it, and the per-tool credential isolation fix that eliminates the attack surface entirely.
Read the post → -
2026-06-02 · Forensics
Five MCP servers that nearly earned an A — and what they fixed to get there
A forensic look at five near-miss MCP servers that scored B or C on first SkillAudit scan. Each got four or five of six axes right — but one specific pattern tripped them. Covers a database bridge leaking connection strings on error, a filesystem tool with over-declared write permissions, an HTTP proxy with unchecked SSRF, a sandbox with a misleading manifest, and a notification dispatcher vulnerable to tool-description injection. The exact finding and the fix for each.
Read the post → -
2026-06-02 · Buyer Guide
MCP server security for non-technical buyers: a 10-minute field guide
A plain-language guide for team leads evaluating MCP servers for internal adoption. What each SkillAudit axis measures — Security, Credentials, Permissions, Maintenance, Compatibility, Documentation — what A through F grades mean in practice, and a three-outcome decision framework (install / review first / block) for turning an audit report into an adoption decision. No code required.
Read the post → -
2026-06-02 · Research
30-day re-scan delta: what moved on a fresh recrawl of the 101-server MCP corpus
Thirty days after publishing the initial 101-server MCP security scan, we re-ran the full corpus. 7 of 67 F-graded servers improved. 6 were archived or deleted. 88 were unchanged. The vendor-official tier: still zero improvements. Here's the full breakdown — what changed, which disclosure mechanisms drove improvement, and how we project the numbers to move through the rest of 2026.
Read the post → -
2026-06-02 · Engineering
How to write a zero-finding MCP server: a step-by-step construction guide
Only two of the 101 servers in our corpus have zero HIGH findings across all six audit axes. Both share the same construction pattern: schema-first Zod tool design, an allowlist-based SSRF firewall, env-only credential isolation, a command execution allowlist (no
Read the post →shell: true), and a maintenance posture with exact pinning and Dependabot. This guide walks through each step with code you can copy, explains the WHY behind each decision, and closes with a complete reference skeleton that passes all six axes out of the box. -
2026-06-01 · Research
MCP server security in 2026: state of the ecosystem mid-year update
Six weeks after publishing the 101-server corpus scan: 36.7% SSRF, 43% unsafe command-exec, 79% vendor-official F grades. Not a single vendor-official server improved after six weeks of public disclosure. Here's what changed, what didn't, where the attack surface is growing in H2 (multi-agent pipelines, event-driven architectures, GraphQL/gRPC proxies), and what a healthy MCP security posture looks like heading into the second half of 2026.
Read the post → -
2026-06-01 · Engineering
The MCP server permissions checklist: 5 questions before you request org scope
The permissions axis is where the blast radius math is most unforgiving: a server that requests
Read the post →admin:organd has an SSRF vulnerability doesn't have two problems — it has one full-account-takeover problem. This checklist gives you five questions to answer before submitting to the Anthropic Skills Directory: GitHub Apps vs PATs, minimal scope declaration, permanent vs ephemeral tokens, credential-in-URL patterns, and LLM-controlled credential selection. Code examples for every fix and the exact SkillAudit finding for each. -
2026-06-01 · Engineering
MCP server dependency pinning: a supply chain incident walkthrough
A floating
Read the post →^in yourpackage.jsonis a standing invitation for npm to fetch whatever the upstream maintainer publishes next. This post walks through a concrete incident timeline — a compromised transitive dependency silently exfiltrating SSH keys and AWS credentials from 400 installers — then shows the three changes that prevent it: exact version pinning, lockfile integrity enforcement withnpm ci, and a patch-only Dependabot configuration that delivers security updates within 24 hours of advisory publication. -
2026-06-01 · Research
Vendor-official vs community MCP servers: updated security grade breakdown
Six weeks after our April 2026 scan, the grade distribution has not materially shifted: 79% of vendor-official MCP servers in our corpus earn F, versus 26% of community-maintained servers. Only one vendor-official server (Microsoft Playwright) earns A. The counterintuitive finding: indie devs who understand the SSRF and credential threat model outperform large corporate teams who ship MCP servers as afterthoughts. Grade distribution tables, three structural reasons behind the gap, what changed after public disclosure, and what it means for Anthropic's directory certification program.
Read the post → -
2026-06-01 · Research
MCP server permission scope patterns — what the corpus shows
68% of corpus MCP servers request org-wide API scopes when only repo-level access is needed. This research post shows the three code patterns behind that number — OAuth app scope over-declaration, permanent tokens where ephemeral tokens would work, and credentials in URL parameters — explains the blast-radius math (SSRF × org-write = full account takeover), and gives the scope-down implementation that eliminates each finding without breaking functionality.
Read the post → -
2026-05-31 · Engineering
GitHub Action gate: enforcing MCP security grades in CI/CD — the complete setup guide
The full CI/CD implementation guide for teams wiring a SkillAudit grade gate into GitHub Actions: lockfile diffing, observe-only mode, multi-agent-client support, org-level reusable workflows, the exception path with expiry tokens, a weekly re-scan cron with Slack alerts on grade regressions, branch protection integration, and the Team-plan version-pinned grade endpoint. Three complete workflow files, copy-paste ready.
Read the post → -
2026-05-31 · Buyer Guide
How to Read a SkillAudit Report — Understanding Every Section of an MCP Security Audit
A complete field guide to every section of a SkillAudit report: what the six axis grades mean (Security, Credentials, Permissions, Maintenance, Compatibility, Documentation), when HIGH vs WARN vs PASS vs INFO applies, the install-gate decision framework for team leads (install / review first / block), and a prioritized fix order for authors. Includes the grade scale (A–F definitions with corpus context), how the badge and public permalink work, and the three gaps the current engine doesn't cover.
Read the post → -
2026-05-31 · Engineering
MCP Server Security Testing: What Static Analysis Catches and What It Doesn't
An honest accounting of the SkillAudit v0.3 engine after 101 servers: what static AST/taint analysis reliably catches (SSRF, command injection, hardcoded secrets, credential echoes), what the LLM-probe layer adds (prompt-injection susceptibility scoring, scope vs. handler drift confirmation), and three finding classes neither layer handles well (cross-tool privilege chaining, long-lived session state, unsafe deserialization). Includes a 9-row coverage table mapping each finding class to each detection layer.
Read the post → -
2026-05-31 · Security Research
MCP Server OWASP Top 10: What the Threat Map Actually Looks Like After 101 Servers
A field guide from running SkillAudit across 101 community and vendor-official MCP servers — which OWASP categories map cleanly onto Model Context Protocol, which stretch, and which three MCP-specific threats (credential echo into tool response, permission scope vs. handler drift, client compatibility drift) have no clean home in either the API Top 10 or the LLM Top 10. With corpus rates, priority order, and specific code examples for each class.
Read the post → -
2026-05-31 · Hardening Guide
MCP Server Security Checklist: 12 Items Before You Publish
Across 101 MCP servers in the public corpus, 42 earned an F — and most of those failures trace back to the same dozen patterns. A 12-item hardening checklist covering every check the SkillAudit engine runs: SSRF prevention, command-exec gates, prompt-injection walls, credential handling, permission scope, dependency pinning, CHANGELOG discipline, client compatibility testing, and runnable documentation. One item per axis, with concrete grep commands for each and code patterns showing the before and after.
Read the post → -
2026-04-30 · Engineering
Anatomy of a credential leak — four patterns across 38 of 101 MCP servers
Of the 101 community Model Context Protocol servers we audited, 38 emit findings on the credentials axis. The leaks group into four named patterns: 64 hardcoded secrets in source across 18 repos (30 OpenAI/Anthropic-style keys, 10 GitHub PATs, 8 Stripe test secrets, 6 AWS access keys, plus Slack and GitHub OAuth), 13 echoes of
Read the post →process.env/os.environto stdout across 7 repos including Klavis-AI, PipedreamHQ, Honeycomb, mcp-use, punkpeye/fastmcp, Stripe agent-toolkit, and Pydantic AI, 1 error-message env-var echo at JetBrains, and 44.envfiles committed to the repo tree across 28 repos. Why credentials are the one axis whose blast radius is unbounded by the host process — every leaked value travels with the LLM conversation. Bad-vs-good code shapes per pattern, install-gate rule, author + buyer checklists. -
2026-04-30 · Research
Nine of 101 most-installed MCP servers are archived — what the maintenance signal looks like in 2026
Of the 101 community Model Context Protocol servers we audited, nine have been declared dead by their maintainers — eight of them vendor-official, including Azure (1,213 stars), Gmail Server (1,098 stars), Mem0, E2B, Pydantic Logfire, PostHog, Honeycomb, and two of Anthropic's own scaffolders. Four more haven't been pushed to in 365+ days; sixty lack a SECURITY.md disclosure file. The maintenance axis is the only one of the six that gets worse over time without anyone touching the code. Full list with grades, days-since-push distribution, and a four-signal install-gate framework. Calendar-axis counterpart to the anatomy-of-an-A post.
Read the post → -
2026-04-30 · Engineering
Anatomy of an A-grade MCP server — five code patterns shared by the 19 that passed our 101-repo audit
Of the 101 community Model Context Protocol servers we audited, 19 earned an A and two earned a perfect 100. Reading their source side by side, the patterns that separate them from the 82 that didn't are five boring habits — no
Read the post →fetch(url)from a tool argument without an allowlist, noexecwith template-string argv, env-vars read once at startup never echoed, narrow verb-shaped tool surface, and current maintenance signal. The single missing piece across 17 of 19 is the same: noSECURITY.md. The two perfect 100s (LangChain MCP adapters, Vectara) are explained, plus the Microsoft Playwright case study (A despiteexecSyncin tests). Author and buyer checklists at the bottom. -
2026-04-30 · Engineering
Engine v0.3 calibration delta — 22 grades moved when surface tiering shipped
SkillAudit engine v0.3 introduces surface tiering — findings in examples, benchmarks, top-level scripts, and installer code now deduct at lower weight than runtime tool surface. Across the 101-repo audit corpus, 22 grades moved: 9 letter promotions (Stripe F→C, Anthropic's MCP TypeScript SDK F→B as the corpus's first B, plus GitHub MCP, Grafana, Pydantic AI, MCP Go SDK, MCP Python SDK, MCP Quickstart, lastmile-ai), 8 within-band lifts (including Vectara A 90→100 — the corpus's second perfect score), and 5 honest cap-fix drops (punkpeye/fastmcp D→F, glips/figma-context-mcp D→F, plus three F-band internal moves) where v0.2's shared-cap bug had been silencing real production-source SSRFs. Every move named, every audit page linked.
Read the post → -
2026-04-30 · Install guide
The MCP install shortlist — 19 community servers that earn an A in our 101-repo audit (April 2026)
Of the 101 most-installed Model Context Protocol servers we audited, 19 earned an A grade. The full shortlist grouped by use case (vector DBs, operational DBs, web fetch, backend platforms, voice, frameworks) — Pinecone, Qdrant, Milvus, Vectara, Meilisearch, Redis, ClickHouse, Couchbase, Snowflake, Exa, FireCrawl, DuckDuckGo, fetch-mcp, Microsoft Playwright, Appwrite, Box, FastAPI-MCP, ElevenLabs, and the LangChain MCP adapters at a perfect 100/100. The buyer-side counterpart to the vendor-official F-grades post.
Read the post → -
2026-04-30 · Playbook
Block 52 of 101 community MCP servers with one CI gate — the 2026 team policy template
A min-grade-C team policy blocks 52 of the 101 most-installed Model Context Protocol servers in 2026, including 29 vendor-official releases your developers would have waved through on brand alone. The full policy paragraph, the 30-line GitHub Action that gates new installs on the SkillAudit grade, the re-scan cadence, the 12-week rollout calendar, and the four week-1 gotchas your security engineer will hit.
Read the post → -
2026-04-29 · Research post
29 vendor-official MCP servers earned an F — every name, every file path
A line-by-line walk through every vendor-official MCP server in our 101-repo corpus that ended at an F grade — Cloudflare, Stripe, Heroku, MongoDB, GitHub, AWS, Azure, Auth0, Sentry, PostHog, Anthropic's own SDKs, and 18 more. Real findings, real file paths, honest calibration notes on where the engine is unambiguous and where it is still learning to subdivide runtime tool surface from examples and scripts.
Read the post → -
2026-04-24 · Research post
We scanned 52 MCP servers — 56% had SSRF, 44% leaked credentials
SkillAudit's first 52-repo scan — vendor-official releases from AWS, Cloudflare, Stripe, MongoDB, Heroku, Redis, and indie frameworks — with every report public. Real grades, ranked F offenders, A-grade counterfactuals. (Corpus since expanded to 71; see the UPDATE banner inside the post.)
Read the post → -
2026-04-23 · Launch post
Why 36.7% of community MCP servers fail a basic SSRF check
A public 2026 scan of community Model Context Protocol servers found SSRF in more than a third of them and unsafe command execution in 43%. Here is what that actually looks like in code, why existing dependency scanners miss it, and what we built about it.
Read the post →