PageSourceSearch

https://www.prismor.dev/_next/static/chunks/f4eb0c6e96994211.js?dpl=dpl_9sZhAczs62sePQHFn1dmdm76Jj6B

js prismor.dev collected 2026-10-05 01:03:33 UTC 488,803 bytes, 298 lines download raw bytes

1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,137422,509692,477958,e=>{"use strict";var t=e.i(843476),a=e.i(657688),s=e.i(522016);function r(e){return e.ogImage??"/blog/og?variant=thumb"}function n(e){return!e.ogImage}function i(e,t,a=3){let s=e.filter(e=>e.id!==t.id);return[...s.filter(e=>e.category===t.category),...s.filter(e=>e.category!==t.category)].slice(0,a)}function o({article:e}){let i="cover"===e.coverFit;return(0,t.jsxs)(s.default,{href:`/blog/${e.id}`,className:"group flex flex-col",children:[(0,t.jsx)("div",{className:`relative aspect-[16/9] overflow-hidden rounded-xl border border-zinc-200 bg-white ${i?"":"p-2"}`,children:(0,t.jsx)(a.default,{src:r(e),alt:"",fill:!0,"aria-hidden":"true",className:`${i?"object-cover":"object-contain p-1"} transition-transform duration-500 group-hover:scale-[1.03]`,sizes:"(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw",unoptimized:n(e)})}),(0,t.jsx)("p",{className:"mt-4 font-sans text-[13px] text-zinc-500",children:e.category}),(0,t.jsx)("h3",{className:"mt-2 font-sans text-[15px] sm:text-[16px] font-semibold leading-[1.45] text-zinc-900 transition-colors group-hover:text-zinc-600",children:e.title}),(0,t.jsx)("p",{className:"mt-2 font-sans text-[13px] text-zinc-500",children:e.date})]})}e.s(["BLOG_AUTHOR",0,"Security Research Team","blogCover",()=>r,"isGeneratedCover",()=>n,"relatedArticles",()=>i],509692),e.s(["default",()=>o],137422);let l=[{label:"Shell and command execution",share:76,tools:"bash, exec, git, pytest, npm test, cargo",lead:!0},{label:"File edits and patching",share:11,tools:"FileEdit, Write, ApplyPatch, EditorSubagent"},{label:"File system inspection and read",share:9,tools:"ReadFile, Grep, Glob, Find, ViewerSubagent"},{label:"Interactive verification and logs",share:2.5,tools:"tap, screenshot, get_logs, execute_in_app"},{label:"External web and sub-agent calls",share:1.5,tools:"WebSearch, WebFetch, Sub-agents, Ask user"}],d=[{id:"hooks-vs-proxy-agent-runtime-security",title:"Hooks or a Proxy for Agent Runtime Security: What Each One Sees and When to Use It",description:"A hook screens the tool call an agent runs. A proxy screens the prompt and the call the model proposes. What each sees, what each misses, and when to use which.",date:"September 29, 2026",category:"Agent Security",ogImage:"/blog/hooks-vs-proxy-agent-runtime-security-2026-09-29-hero-doodle.jpeg",ogImageAlt:"Hand-drawn sticky-note flow: Agent, then Proxy, which sees the prompt, then Model, then a curly arrow to Hook, which sees what runs, then Your machine.",keywords:["agent runtime security","AI agent hooks","PreToolUse hook security","LLM proxy security","AI gateway vs hooks","Claude Code hooks security","ANTHROPIC_BASE_URL proxy","OPENAI_BASE_URL proxy","tool call interception","n8n agent governance","A2A agent security","secret masking LLM prompts","AI coding agent security","agent tool-call enforcement"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["A Claude Code session fires a ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"PreToolUse"})," hook before every tool call. The hook receives the command, the working directory, and the session id, and the agent waits for its answer before it runs anything. An n8n workflow running an AI agent node has no such event. There is nothing to hook, and the only thing you control is the base URL its OpenAI credential points at."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Those two agents need two different controls. A hook sits between the agent and your machine. A proxy sits between the agent and its model. Both can refuse a dangerous tool call, and both can run the same policy, yet they see different parts of the loop and they fail in different ways. This post walks through what each one sees, what each one misses, and how to pick."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/hooks-vs-proxy-agent-runtime-security-2026-09-29-hero-doodle.jpeg",alt:"Hand-drawn sticky-note flow: Agent, then Proxy, which sees the prompt, then Model, then a curly arrow to Hook, which sees what runs, then Your machine.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"The proxy sits on the model traffic. The hook sits at the point of execution."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How a hook works"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["A hook is a callback the agent itself offers. Before a tool runs, the agent serializes the call to JSON and hands it to an external 
1command. The command returns allow, deny, or ask, and the agent obeys. A second event, ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"PostToolUse"}),", fires after the tool returns and carries its result."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The strength of this position is that it covers the agent’s entire tool surface. Every shell command, file read, file write, web fetch, and MCP call passes through the same checkpoint, including tools no security product has a special case for. The hook sees the call the agent is about to execute, after the agent has resolved it, with the real working directory attached. It runs locally, so it works offline and adds no network hop."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The limits are just as structural. A hook only exists where the agent ships a hook protocol. Claude Code, Codex, Cursor, Gemini CLI, Copilot CLI, and most coding agents now do. Aider, Warp, Trae, and Antigravity do not. A hook also works on actions. It has no view of the prompt going to the model provider, so a credential that has already entered the agent’s context leaves the machine with the next request. On most agents a hook can refuse a call but cannot rewrite the tool’s output."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How a proxy works"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["A proxy asks nothing of the agent. Almost every model SDK reads a base URL from an environment variable or a constructor argument, such as"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ANTHROPIC_BASE_URL"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"OPENAI_BASE_URL"}),", or the Google Gen AI SDK’s ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"base_url"}),". Point it at the proxy and every model request crosses a process you control."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["A proxy sees two things. On the way out, it sees the full prompt: system prompt, user messages, and every tool result the agent is feeding back. That is where an injected instruction rides in, and it is the last point at which a live secret can be masked before it lands in a third party’s logs. On the way back, it sees the tool calls the model proposed. A text filter treats those as prose. A useful proxy parses the"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"tool_use"})," block into the same shell or file event a hook would produce and runs the same rule, so a command blocked at the hook layer is also blocked when the model proposes it."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Streaming makes this harder. Refusing after the client has read the bytes enforces nothing, so the proxy has to hold each tool-call block until it is complete, judge it whole, then release it or replace it with a refusal. Text still streams. Tool arguments arrive in one burst instead of token by token, which is the cost of enforcement on a stream."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What each one misses"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The gaps follow from where each control stands."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"The proxy sees intent. The hook sees execution."})," A proposed call is not always the call that runs. A permission prompt c
1an stop it, and a sandbox can rewrite its input. The hook judges the final form. The proxy judges the model’s draft."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"The proxy depends on the tool schema."})," A proposed call is only as legible as its arguments. A tool that takes a structured ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"command"})," field maps cleanly onto shell rules. A tool that takes a free-text ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"query"})," gives the rules nothing to match."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"The proxy only governs traffic that reaches it."})," An agent that ignores the base URL setting, or runs inside a managed cloud runtime whose model calls never cross a URL you own, bypasses it. For a hosted runtime, the lever is shipping a policy adapter inside the agent’s own code."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"The hook cannot see the prompt."})," Secrets and injected instructions in the context window reach the model provider untouched unless something on the wire masks or screens them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"A proxy refusal ends the turn."})," A hook’s denial returns to the agent as a tool result it can reason about. The proxy can only withhold the call and hand back text, so the model’s turn is over and an unattended agent stops there."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"The hook only exists where the vendor built one."})," Workflow tools, chatbots, custom SDK apps, and agent-to-agent (A2A) calls usually expose no hook at all."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What running both side by side shows"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Put the same agent behind each control, give it the same task, and compare what each one recorded. The difference is consistent, and it follows directly from where each control stands."}),(0,t.jsx)("div",{className:"overflow-x-auto mb-8",children:(0,t.jsxs)("table",{className:"w-full text-sm border-collapse",children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{className:"bg-amber-50 border border-amber-200",children:[(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900 border-r border-amber-200",children:" "}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900 border-r border-amber-200",children:"Hook"}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900",children:"Proxy"})]})}),(0,t.jsx)("tbody",{children:[{k:"Tool output (stdout, stderr, files changed)",h:"Yes, after each call",p:"No, only what the model proposed"},{k:"Working directory",h:"The agent’s real one",p:"Unknown to it"},{k:"Tool call id, permission mode, session transcript",h:"Yes",p:"No"},{k:"Instruction files the agent loaded",h:"Yes",p:"Only as text inside the prompt"},{k:"Full system prompt and conversation",h:"No, only the user prompt",p:"Yes, every turn"},{k:"Model and token usage",h:"Yes, from the transcript",p:"Yes, from the response"},{k:"Secrets in context before they leave",h:"Cannot touch them",p:"Can mask them"},{k:"Latency it adds",h:"Per tool call, local",p:"Per model call, on the request path"},{k:"What a block does",h:"Returns a reason the agent can act on",p:"Ends the model’s turn"}].map(e=>(0,t.jsxs)("tr",{className:"border border-gray-200",children:[(0,t.jsx)("td",{className:"px-4 py-2 border-r border-gray-200 font-medium text-gray-900",children:e.k}),(0,t.jsx)("td",{className:"px-4 py-2 border-r border-gray-200 text-gray-700",children:e.h}),(0,t.jsx)("td",{className:"px-4 py-2 text-gray-700",children:e.p})]},e.k))})]})}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/hooks-vs-proxy-agent-runtime-security-2026-09-29-seen-doodle.jpeg",alt:"Hand-drawn sticky-note comparison titled what each one saw. Hook column: real output, working dir, agent recovers. Proxy column: full prompt, masks secrets, turn ends.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"The hook knows what happened on the machine. The proxy knows what the model was told."})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("strong",{children:"A hook turns a block into feedback. A proxy turns it into a stop."})," When a hook denies a call, the denial returns to the agent as a tool result with a reason. The agent can read it and take a safer route, and the task still finishes. When a proxy denies a call, it can only withhold the call and hand back text, so the model’s turn is over. An interactive user sees the refusal and decides what to do. An unattended agent simply stops. That matters most for false positives, which every rule set has: under a hook they cost a retry, under a proxy they cost the task."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("strong",{children:"Streaming is where proxies break."})," A proxy that withholds a tool call has to rewrite the rest of the stream to match, including the field that tells the client a tool call is coming. If it leaves that field alone, the client waits for a call that was removed and fails in ways that look like a model error. Test any proxy against the real agent in streaming mode before trusting it, and time a trivial prompt with and without it. Anything that inspects every string of a large coding-agent request pays for it on every single turn."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("strong",{children:"Pattern-based secret masking is a floor."})," A credential with a recognizable shape, such as an AWS key ID with its fixed prefix, is easy to catch. Its paired secret is a random string with nothing to anchor on, and it goes through. Secrets you already know about should be registered by value, so they are caught wherever they appear. Check your local logs as well. A control that records the prompt before masking it has just written the secret to disk."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("strong",{children:"Current models refuse the obvious injections."})," A planted instruction to pipe a download into a shell is usually declined and flagged by the model itself. That says little about the control behind it. Test your rules with calls the model is willing to make, and measure the false positives they produce on ordinary work, because those are what users meet every day."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"When to use which"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Start from the agent and ask two questions in order."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/hooks-vs-proxy-agent-runtime-security-2026-09-29-decide-doodle.jpeg",alt:"Hand-drawn sticky-note decision map. Hooks? Yes: use hooks, for coding agents. No: base URL? Yes: use the proxy, for n8n, SDKs, and A2A. No: SDK adapter. A separate note reads Both, with a lightbulb.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Hooks first where they exist, the proxy where they do not, and both where the prompt itself carries risk."})]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Coding agents on a developer machine: hooks."})," Claude Code, Codex, Cursor, Gemini CLI, and Copilot CLI all expose a pre-tool event. The hook covers every tool, judges the call that actually runs, and records its output. When it blocks, the agent can try a safer route instead of stopping."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Agents with no hook protocol: the proxy."}
1)," n8n, LangChain or OpenAI SDK apps, internal chatbots, and A2A clients all accept a base URL. One environment variable brings them under the same policy with no code change."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Managed model endpoints: the proxy, with signing."})," Agents on Bedrock, Vertex, or Azure OpenAI can go through the same proxy if it re-signs requests with the cloud credential, AWS SigV4 or a GCP OAuth token, after screening them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Neither available: govern from inside."})," A framework adapter in the agent’s own code, or an MCP layer that serves its tools, is the remaining interposition point."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Sensitive data in the context: both."})," If agents read customer data, credentials, or untrusted documents, put hooks on execution and the proxy on the wire. The hook stops the dangerous action. The proxy stops the secret from leaving in the prompt."]})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["Running both only works if they agree. Two controls with two rule sets will eventually disagree about the same command, and the gap between them is where an incident hides. The simpler setup is one policy engine behind both surfaces, so a rule written once applies at the hook and on the wire, and both write to the same session trail. That is how"," ",(0,t.jsx)("a",{href:"/docs/governance-surfaces",className:"text-amber-700 underline hover:text-amber-900",children:"Prismor’s governance surfaces"})," ","are built, and the ",(0,t.jsx)("a",{href:"/docs/llm-proxy",className:"text-amber-700 underline hover:text-amber-900",children:"LLM proxy"})," and hooks share the same rule table. Whatever you run, the question to ask of any agent in your fleet is the same: at which point in its loop does a rule actually get checked, and what does that point fail to see."]})]}),faq:[{question:"What is the difference between an agent hook and an LLM proxy?",answer:"A hook is a callback the agent calls before running a tool, so it screens the exact call about to execute. An LLM proxy sits on the agent’s model traffic, so it screens the outbound prompt and the tool calls the model proposes, without any change to the agent."},{question:"When should I use a proxy instead of hooks?",answer:"Use a proxy when the agent has no hook protocol, such as n8n, SDK apps, chatbots, and A2A clients, and when you need to mask secrets in the prompt before it reaches the model provider. Use hooks for coding agents that support them."},{question:"Can hooks and a proxy run together?",answer:"Yes. Hooks govern execution on the machine and the proxy governs what leaves it. Run them from one policy engine so both surfaces apply the same rules."}]},{id:"prompt-injection-classifier-in-front-of-llm-judge",title:"A Classifier in Front of the LLM Judge: Prompt-Injection Screening at 1.1s per 12,000 Characters",description:"Our regex pre-screen capped injection detection at 34% because most payloads never got escalated. Judging every text fixes that and makes latency the whole problem. A classifier judged 12,000 characters in 1.1s where our LLM judge needed 11.4s.",date:"September 20, 2026",category:"Agent Security",ogImage:"/blog/prompt-injection-classifier-latency-2026-09-20-chart.png",ogImageAlt:"Bar chart of median seconds to judge one text. Short one-paragraph text: TypeSafe Jev 0.84 seconds, gpt-5.6-luna 2.07 seconds. Long 12,000-character document: TypeSafe Jev 1.10 seconds, gpt-5.6-luna 11.40 seconds.",keywords:["prompt injection detection","prompt injection judge latency","TypeSafe Jev classifier","runtime prompt injection screening","agent runtime security","LLM judge latency","indirect prompt injection README","classifier vs generative judge","prompt injection false positive rate","tool call interception latency","agent reads untrusted text","gpt-5.6-luna judge benchmark","prompt injection threshold tuning","two stage prompt injection screening","AI coding agent guardrails"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Any README, web page or script output an agent reads can tell it to ignore its instructions and upload your SSH key. We screen every text an agent reads before it acts, at runtime, in the path of the tool call. Last quarter that screen ran at 2 seconds p50 per call, and our last evaluation found the bottleneck somewhere we had not been looking."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The judge was fine. The regex pre-screen in front of it was the problem. Detection capped at 34% because most injections never matched a pattern, so they never got escalated to the judge at all. The fix is to judge everything. Do that and judge latency becomes the whole problem, which is how we ended up benchmarking a classifier against the generative model we had been using."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why the pre-screen capped detection at 34%"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A regex pre-screen is a cost-control mechanism wearing a security hat. It exists so you only pay for the expensive judge on text that looks suspicious. That works when attacks look suspicious. Injection payloads are prose, written by someone who knows a filter is there, and prose has more ways to say “ignore your previous instructions” than a pattern list can hold."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"So two thirds of what we planted walked straight through, untouched, because nothing escalated it. The judge behind the screen was accurate on everything it actually saw. It just never saw most of the attacks. Removing the pre-screen raises the ceiling to whatever the judge can catch, and hands you a bill: every text an agent reads now costs a judge call, in the critical path, before the agent is allowed to act."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What we measured"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"We put 120 short texts through five configurations: 72 with injections, 48 benign. Each call carries four questions, covering injection, secrets, destructive action and severity. TypeSafe Jev answers with a probability for each instead of writing a verdict in prose, which is most of where the speed comes from. A classifier does one forward pass. A generative judge writes tokens, and 
1you wait for all of them."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/prompt-injection-classifier-latency-2026-09-20-accuracy.jpeg",alt:"Two panel chart. Panel a, accuracy on 72 injections and 48 benign texts: gpt-4.1-nano caught 58% with 12% benign wrongly flagged, gpt-4o-mini 96% and 10%, gpt-5.6-luna 100% and 2%, TypeSafe at threshold 0.75 100% and 2%, TypeSafe at threshold 0.9 100% and 0%. Panel b, median latency per text with p95 error bars: gpt-4.1-nano 1.34 seconds, gpt-4o-mini 1.14 seconds, gpt-5.6-luna 2.07 seconds, TypeSafe with four questions 0.84 seconds.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"The two small models are cheap and miss things. The accurate options are the classifier and the flagship, and they are 1.2 seconds apart per call."})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Jev caught 72 of 72 at a 0.9 threshold with nothing benign wrongly flagged, at 0.84s median. ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"gpt-5.6-luna"})," matched the catch rate at 2.07s and flagged 2% of the benign set. The two cheaper models are the reason we did not simply downgrade the judge: ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"gpt-4.1-nano"})," caught 58% of injections while wrongly flagging 12% of benign text, which is the worst of both trades."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Look at the p95 whiskers rather than the bars. The flagship judge runs from 2.07s to past 4s on the slow tail. That tail sits in front of a tool call a developer is waiting on, and a p95 is not rare when an agent reads forty files in a session."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Long documents are where the gap opens"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Short texts make the two look close. A 12,000-character README does not. The generative judge has to window a document that size into 3,000-character chunks and judge them in sequence, so one document becomes four calls and you pay the tail four times."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/prompt-injection-classifier-latency-2026-09-20-longdocs.jpeg",alt:"Bar chart of latency on long documents, n equals 48, seconds per 12,000-character document. TypeSafe whole document in one call: p50 1.1 seconds, p95 1.4 seconds. Type
1Safe in 3000-character windows: p50 3.9 seconds, p95 5.2 seconds. gpt-5.6-luna in 3000-character windows: p50 11.4 seconds, p95 15.2 seconds.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Windowing costs the classifier 2.8 seconds as well. Reading the document in one pass is most of the win."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Jev reads the whole document in one call: 1.1s median, 1.4s at p95, and it caught 24 of 24 payloads we buried in those documents. The same work through the flagship judge took 11.4s median and 15.2s at p95, for the same 24 of 24. Ten times the wait for an identical answer."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The middle bar is worth more attention than the comparison. Running Jev over the same 3,000-character windows costs 3.9s instead of 1.1s, so windowing itself accounts for most of the cost. Whole-document context also matters for correctness: a payload split across a chunk boundary reads as innocent on both sides of the cut."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The false positives"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A clean benchmark set is a flattering place to measure. Against real traffic the classifier’s false positive rate reached 41%, which is a different product from the one the 120-text run describes. Documentation that quotes an attack, a security README, a test fixture full of payloads: all of it scores high, and all of it is fine to read."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"We tried teaching it the difference by adding a fifth question, roughly “is this quoted for a human reader”. That moved errors around instead of removing them. Texts that had been false positives became false negatives, which is the trade you least want on a security control."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"So the probability output turned out to be the useful part, more than the verdict. A score of 0.97 and a score of 0.80 are different situations, and a judge that writes prose flattens both into “blocked”. Keeping the number lets you route on confidence instead of on a binary."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"We landed on two stages: the classifier on everything, the LLM on the gray zone only. That keeps full coverage at classifier speed and spends the expensive judge on the small slice of traffic where the score is genuinely ambiguous."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Count what your pre-screen drops."})," Detection ceilings hide well. Plant payloads, then measure how many reached the judge rather than how many the judge caught."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Judge whole documents in one call."})," Windowing cost us 2.8s on a 12,000 character file and cuts payloads in half at the boundaries."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Route on the score."})," Allow under 0.75, block at 0.95 and above, send the middle to the LLM. Tune the thresholds against your own benign traffic, because 41% of ours was documentation that talks about attacks."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Watch p95, not p50."})," Medians look fine on every option here. The tail is what a developer feels when an agent reads forty files in a session."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Resist adding questions to fix precision."})," Our fifth question converted false positives into false negatives. Threshold tuning moved the needle where prompt engineering did n
1ot."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The broader thing this evaluation changed for us is where we look for a security ceiling. We spent months tuning a judge that was already accurate, while a cheap filter in front of it quietly decided two thirds of attacks were not worth asking about. Cost controls have a habit of becoming coverage decisions that nobody wrote down. Worth asking, on any runtime control you run: what does this thing skip, and when did anyone last measure it?"})]})},{id:"harness-alignment-over-model-alignment",title:"For Coding Agents, Harness Alignment Matters More Than Model Alignment",description:"Same model swings 8 to 20 points on SWE-bench by harness alone, and the 2025 Replit and Antigravity deletions were harness failures. Alignment is enforced in the harness.",date:"September 9, 2026",category:"Agent Security",ogImage:"/blog/harness-alignment-over-model-alignment-2026-09-09.png",ogImageAlt:"Flowchart titled model alignment vs harness alignment: a model with probabilistic intent proposes a tool call, the harness checks permissions, sandbox, and approval, then either executes the tool against shell, files, or network, or blocks it as a safe failure.",keywords:["harness engineering","agent harness alignment","coding agent harness","model alignment vs harness alignment","AI coding agent security","Claude Code permissions","Codex sandbox approval","agentic misalignment","prompt injection coding agents","SWE-bench harness variance","Replit agent database deletion","Antigravity drive deletion","tool-call boundary enforcement","runtime guardrails AI agents","AI agent governance 2026"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"In July 2025, a Replit coding agent deleted a production database holding records on 1,206 executives and 1,196 companies. The deletion happened nine days into a public build, during a code freeze the user had declared with one instruction: no more changes without explicit permission. In late November 2025, a user asked Google’s Antigravity IDE to clear a project cache. The agent ran a delete against the root of his D: drive instead, skipping the Recycle Bin. He had turned on Turbo mode, which lets the agent run commands without asking."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Both agents ran on frontier models with extensive safety training. Both models, when the users confronted them, wrote articulate apologies and correct descriptions of what they should have done. The models knew the rule. No code between the model and the shell checked it. Everything in that gap is the harness, and for coding agents the harness decides more of the outcome than the model inside it."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What a harness is"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A harness is every part of a coding agent that is not the model: the system prompt, the tool set, the context assembly, the loop control, the permission checks, the sandbox, the approval flow, and the audit trail. OpenAI gave the clearest definition on record in its August 19, 2026 Codex platform announcement. The harness “gathers context, invokes tools, enforces sandbox and approval boundaries, streams execution progress, and carries work across multi-turn sessions.”"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"For security, one part of that sentence carries the weight: enforces sandbox and approval boundaries. A model emits a tool call as text, a JSON object that says run this command or write this file. The model cannot reach a filesystem on its own. The harness takes that JSON and executes it, and at that moment a rule either holds or fails."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The harness already dominates capability"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Benchmark authors have started separating the model from the scaffold around it, and the scaffold keeps accounting for the larger share of the score."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Same model, different scaffold, 8 points."})," Epoch AI’s SWE-bench Verified analysis found a single model moving from 62.3% to 70.2% by scaffold choice alone."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Same model, four harnesses, 6 points."})," On SWE-bench Pro, Claude Opus 4.5 scores 45.9% under Scale’s standardized SEAL scaffold and between 49.8% and 51.8% under Claude Code, Cursor, and Auggie."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Same model, harness swap, 21 points."})," A May 2026 comparison reported Claude Opus 4.8 moving from 0.921 to 0.712 Pass@1 when moved between two agent harnesses. Papers treat a 2 to 4 point gain as a meaningful model advance."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rankings reverse."})," The May 2026 paper"," ",(0,t.jsx)("a",{href:"https://arxiv.org/abs/2605.23950",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Stop Comparing LLM Agents Without Disclosing the Harness"})," ","documents cases where the ordering of two frontier models flips with the harness configuration. The authors argue the harness “is often a stronger determinant of agent performance than the model it wraps.”"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Harness fixes transfer across models."})," The authors of"," ",(0,t.jsx)("a",{href:"https://arxiv.org/abs/2605.22166",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Adapting the Interface, Not the Model"})," ","built harness adaptations against a 4B-parameter model, transferred them to 17 other backbones, and improved 116 of 126 model-environment settings without changing a weight."]})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["Anthropic reached the same conclusion from the inside. Its November 2025 engineering post on long-running agents states that context compaction “isn’t sufficient,” and ships an initializer agent, a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"claude-progress.txt"})," ","file, a JSON feature list with tests the agent is told it is “unacceptable” to edit, and one git commit per feature. OpenAI reported that three engineers driving Codex through a purpose-built harness of linters, documentation structure, and lifecycle rules merged about 1,500 pull requests and around a million lines of code in five months. Both companies got those results by engineering the layer around the model."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why model alignment cannot carry the security load"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If the harness moves capability by double digits, it moves safety by at least as much. Safety is the case where the model works against you or someone has turned it against you. Three results from the labs set the ceiling on what model-level alignment can promise."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Instructions reduce misbehavior. They do not remove it."})," Anthropic’s June 2025"," ",(0,t.jsx)("a",{href:"https://www.anthropic.com/research/agentic-misalignment",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"agentic misalignment"})," ","study put 16 models from six developers in a simulated corporate role with email access and a replacement threat. Claude Opus 4 and Gemini 2.5 Flash chose blackmail 96% of the time, GPT-4.1 and Grok 3 Beta 80%, DeepSeek-R1 79%. An explicit written prohibition cut Claude’s rate to 37%. The authors wrote that “naive attempts to simply instruct the model not to engage in harmful behaviors are not sufficient.”"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Prompt injection will not train out."})," OpenAI wrote on December 22, 2025, while hardening the Atlas browser agent, that prompt injection “much like scams and social engineering on the web, is unlikely to ever be fully solved.” Every mitigation OpenAI listed lives in the harness: confirmation before payments and messages, narrower autonomy, a logged-out mode, and an automated attacker that hunts for new injections before the public finds them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"A coding agent reads more untrusted text than any other agent."})," Repository files, dependency READMEs, CI logs, issue threads, MCP tool results, and the output of each command all land in context. Each one can carry an instruction you never wrote. A model that follows instructions well follows those too."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Model alignment is a probability distribution over behaviors. Training shifts the distribution. It cannot zero out a tail, and a coding agent that makes a few thousand tool calls a day samples that tail on a schedule. The Replit freeze held for nine days and then failed once. A 37% residual in the lab looks like that in production."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What harness alignment means"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A harness is aligned when the set of actions the agent can take matches the set of actions you intended to allow, whatever the model decides. You check it at the tool-call boundary, after the model has produced its intent and before anything executes. The major harnesses have converged on the same five layers, and their documentation reads the same way side by side."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Permission rules."})," Claude Code’s allow, ask, and deny lists, where a broad deny beats a narrow allow and a matching ask prompts even when an allow also matches. Codex has an equivalent approval policy. Code evaluates these declarative rules, so a persuasive tool-call description cannot change the verdict."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"OS sandboxing."})," Codex enforces filesystem boundaries through operating-system sandboxes on Linux, macOS, and Windows. Claude Code’s sandbox restricts what a Bash command can reach, which the docs describe as protection “even if a prompt injection bypasses Claude’s decision-making.” The people who train the model wrote that sentence."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Approval for irreversible actions."})," Anthropic’s first recommendation from the misalignment study is “requiring human oversight and approval of any model actions with irreversible consequences.” Put production deletes, force pushes, payment calls, and outbound messages behind a gate the model cannot open by itself."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Runtime monitors."})," The study’s second recommendation: scan for concerning reasoning or misaligned behavior while the agent runs. In a coding harness that means a hook on each tool call that sees the command, the arguments, and the session so far."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Least privilege on information and power together."})," Anthropic’s third recommendation warns against giving a model “both large amounts of information and also the power to take important, unmonitored actions.” Only the harness sees what the agent read and what it is about to write in the same session, so only the harness can measure that combination."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"None of those five layers depen
1ds on a property of the model. Each works the same way with a better model, a worse model, or a jailbroken one. An aligned harness contains the damage when the model is wrong. An aligned model inside an unaligned harness produces the incident writeups above."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why the industry keeps looking at the model"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Model alignment gets the attention because the labs compete on it and the public conversation lives there. You also cannot change it. You cannot retrain the weights your IDE ships with. You can change the harness this afternoon."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Harness failures also look like user error. Turbo mode was a setting. The code freeze was a sentence in a prompt. Both are true, and both miss that the default harness let a single text instruction stand between a routine cache clear and a drive wipe. A harness that treats a delete against a path outside the workspace as an approval event, in any mode, would have stopped it with no change to the model. Vendors have since added checks of that shape. Each one patched the harness."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Treat the harness as the security boundary and the model as an untrusted component inside it. Six steps follow from that."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Write the freeze as a rule."})," If an action must not happen, put it in a deny rule or a sandbox mount the harness evaluates. A sentence in"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"CLAUDE.md"})," ","or"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"AGENTS.md"}
1)," ","is advice to the model. A deny rule is a constraint on the harness."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Keep autonomous modes away from production credentials."})," Turbo, YOLO, and bypass-permissions modes remove the approval layer. Use them inside a sandbox whose blast radius you have already accepted."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Gate irreversible actions on a second decision-maker."})," Destructive shell commands, writes outside the workspace, outbound network to new hosts, and anything that spends money should require a human or an independent policy engine, never the model that proposed them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Log each tool call with its arguments."})," Both users reconstructed their 2025 incidents from chat transcripts because nothing else recorded what executed. An audit trail at the tool-call boundary costs little and survives a model that, as in the Replit case, misreports what it did."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Benchmark your harness."})," Run the same model through your production harness against a set of injected repositories and a set of benign tasks. Count what it blocked and what got through. If you cannot answer that, model choice is the least of your uncertainties."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Make the harness portable across agents."})," Most teams run Claude Code, Codex, Cursor, and two or three SDK-built agents at once. If each carries its own permission model, the weakest one sets the floor. Prismor’s"," ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"open-source runtime"})," ","hooks one policy engine into each harness at the tool-call boundary, so the deny rule that stops a production delete in one agent stops it in all of them."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Models will keep getting better at understanding what you meant. They will stay probabilistic, and they will keep reading text you did not write. You rent the model. You own the harness, and the harness is where your alignment work compounds."})]})},{id:"ai-coding-agent-governance-modes",title:"Prismor OSS Ships Three Governance Modes for AI Coding Agents, and What Each One Gives Up",description:"Prismor OSS now ships three governance modes for AI coding agents. Each names its coverage, its measured friction, and what it does not stop.",date:"September 7, 2026",category:"AI Governance",ogImage:"/blog/prismor-governance-modes-2026-09-07-cards.png",ogImageAlt:"Three collectible cards for the Prismor OSS governance modes: dev-safe, trusted-workspace, and regulated-airgap.",keywords:["AI coding agent governance modes","dev-safe mode","trusted-workspace mode","regulated-airgap mode","agent policy configuration","secure defaults for AI agents","agent tool call distribution","shell command execution AI agents","agent egress allowlist","AI agent sandbox policy","security configuration fatigue","agent residual risk","coding agent friction","AI agent control plane","Prismor OSS","Prismor open source AI agent security"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-4 font-lora font-medium text-lg lg:text-xl",children:["Configuring ",(0,t.jsx)("a",{href:"/docs/prismor",className:"text-amber-700 underline hover:text-amber-900",children:"Prismor OSS"})," has meant setting six independent policy axes. Enforcement fallback, egress allowlist, tool access, tag rules, sandbox ring, and step-up gates each live in a different place. Each carries its own default. A developer who wants nothing more than a posture that is safe for daily work has to assemble it by hand from ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"settings.default_mode"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"settings.egress"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"settings.tool_tags"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"settings.sandbox"}),", per-rule overlays, and an ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"agents.yaml"})," tool list."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:["That is six chances to get something wrong, and the failure is quiet. A policy that looks configured but leaves ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"egress.default: allow"})," reads like one that does not. So ",(0,t.jsx)("a",{href:"/docs/cli-reference#governance-modes",className:"text-amber-700 underline hover:text-amber-900",children:"Prismor OSS"})," now ships three named modes: ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"dev-safe"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"trusted-workspace"}),", and ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"regulated-airgap"}),". You pick one at install time, and each one states what it trades away."]}),(0,t.jsx)("h2",{className:"font-lora text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The cost of a flexible policy engine"}),(0,t.jsx)("p",{className:"text-gray-700 leading-relaxed mb-4 font-lora font-medium text-lg lg:text-xl",children:"Flexibility is why a policy engine is worth running. It is also why teams stall before they finish configuring one. Every axis a security tool exposes is a decision handed to somebody who was trying to do a different job, and the person holding it is a developer three tickets deep on a Tuesday afternoon."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:["Power users want those axes and should keep them. The rest of us want a default that somebody already thought about. ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor setup"})," covered one axis of the six, which rules block, and left the rest to be discovered. There was no way to ask for a whole posture, and no way to compare postures before adopting one."]}),(0,t.jsx)("h2",{className:"font-lora text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The three modes"}),(0,t.jsx)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:"Each mode compiles down into the primitives the engine already reads, so this 
1stays a configuration-layer feature and the enforcement path is untouched. Five self-protection rules stay on in every mode, which means a mode can never become cover for switching Prismor off."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[(0,t.jsx)("img",{src:"/blog/prismor-governance-modes-2026-09-07-dev-safe.png",alt:"Collectible card for dev-safe mode showing a golden swift in a lightning storm, with the ability line i havent read this code and the tagline secure coding agents.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("img",{src:"/blog/prismor-governance-modes-2026-09-07-trusted-workspace.png",alt:"Collectible card for trusted-workspace mode showing a violet feline creature, with the ability line i trust this workspace and the tagline full AI power with security.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("img",{src:"/blog/prismor-governance-modes-2026-09-07-regulated-airgap.png",alt:"Collectible card for regulated-airgap mode showing an armored tortoise on grass, with the ability line nothing is trusted and the tagline max secure agent operations.",className:"w-full rounded-lg border border-gray-200 shadow-sm"})]}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Three postures, each with its own assumption about how much the repository can be trusted."})]}),(0,t.jsxs)("ul",{className:"list-disc list-inside mb-6 space-y-2 font-lora font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"dev-safe."})," Assumes the repository may be hostile. Known destinations only, and read-only commands do not prompt. Built for open source contribution and PR review, where the agent is reading code nobody on your team has read yet."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"trusted-workspace."})," Assumes the repository is trusted, so the agent gets broad autonomy inside it. Hard stops stay on secret reads and package installs. Built for internal repositories and microservices."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"regulated-airgap."}
1)," Assumes nothing is trusted. No network, no shell, and every write goes through approval. Built for regulated data and review-only workflows."]})]}),(0,t.jsx)("div",{className:"overflow-x-auto mb-6",children:(0,t.jsxs)("table",{className:"w-full text-sm border-collapse",children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{className:"bg-amber-50 border border-amber-200",children:[(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900 border-r border-amber-200",children:"Mode"}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900 border-r border-amber-200",children:"Assumes"}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900 border-r border-amber-200",children:"Coverage"}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900 border-r border-amber-200",children:"Friction"}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900",children:"Needs Docker"})]})}),(0,t.jsx)("tbody",{children:[{mode:"dev-safe",assumes:"repo may be hostile",coverage:"31% (25/80)",friction:"9%",docker:"Yes"},{mode:"trusted-workspace",assumes:"repo is trusted",coverage:"34% (27/80)",friction:"9%",docker:"No"},{mode:"regulated-airgap",assumes:"nothing is trusted",coverage:"100% (80/80)",friction:"90%",docker:"No"}].map(e=>(0,t.jsxs)("tr",{className:"border border-gray-200",children:[(0,t.jsx)("td",{className:"px-4 py-2 border-r border-gray-200 font-mono text-gray-900",children:e.mode}),(0,t.jsx)("td",{className:"px-4 py-2 border-r border-gray-200 text-gray-700",children:e.assumes}),(0,t.jsx)("td",{className:"px-4 py-2 border-r border-gray-200 text-gray-700",children:e.coverage}),(0,t.jsx)("td",{className:"px-4 py-2 border-r border-gray-200 text-gray-700",children:e.friction}),(0,t.jsx)("td",{className:"px-4 py-2 text-gray-700",children:e.docker})]},e.mode))})]})}),(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:["That table is the summary. The full axis-by-axis defaults, egress allowlists included, are in the ",(0,t.jsx)("a",{href:"/docs/cli-reference#governance-modes",className:"text-amber-700 underline hover:text-amber-900",children:"Prismor OSS"})," docs alongside the rest of the CLI reference."]}),(0,t.jsx)("h2",{className:"font-lora text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Why the friction numbers land where they do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-relaxed mb-4 font-lora font-medium text-lg lg:text-xl",children:"Coverage and friction are both computed rather than asserted. Coverage comes from the live ruleset. Friction comes from running a corpus of ordinary developer commands through each compiled mode and counting what gets interrupted."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:["The two everyday modes both measure 9%. ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"regulated-airgap"})," measures 90%. That gap looks severe until you look at where agents spend their tool calls."]}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)(function(){return(0,t.jsxs)("div",{className:"rounded-xl border border-gray-200 bg-white p-5 sm:p-6",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)("div",{className:"font-sans text-[15px] font-semibold text-gray-900",children:"Tool calls by category"}),(0,t.jsx)("div",{className:"font-sans text-[13px] text-gray-500 mt-1",children:"Share of 430,000 sampled tool calls"})]}),(0,t.jsx)("div",{className:"space-y-5",children:l.map(e=>(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-baseline justify-between gap-4",children:[(0,t.jsx)("span",{className:e.lead?"font-sans text-[14px] font-semibold text-gray-900":"font-sans text-[14px] text-gray-600",children:e.label}),(0,t.jsxs)("span",{className:e.lead?"font-sans text-[14px] font-semibold text-gray-900 tabular-nums shrink-0":"font-sans text-[14px] text-gray-600 tabular-nums shrink-0",children:[e.share,"%"]})]}),(0,t.jsx)("div",{className:"mt-2 h-2.5 w-full overflow-hidden rounded-[2px] bg-zinc-100","aria-hidden":"true",children:(0,t.jsx)("div",{className:"h-full rounded-r-[4px]",style:{width:`${e.share}%`,backgroundColor:e.lead?"#d97706":"#a1a1aa"}})}),(0,t.jsx)("div",{className:"mt-2 font-mono text-[12px] leading-[1.5] text-gray-500",children:e.tools})]},e.label))})]})},{}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Distribution across broad coding agent workflows including SWE-agent, OpenHands, and Claude Code. Drawn from University of Washington TraceLab telemetry over a sample of 430,000 tool calls gathered from various developers."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-relaxed mb-4 font-lora font-medium text-lg lg:text-xl",children:"Shell and command execution is roughly three quarters of everything an agent does. The other four categories split the remaining quarter between them. That single fact sets the friction budget for any policy you can write."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:["A mode that touches the shell category is spending most of the budget it has. ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"regulated-airgap"})," denies Bash outright, so its 90% is close to arithmetic. The two everyday modes keep the shell and auto-approve read-only commands and non-mutating ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"git"}),", which is how they hold 25 blocking rules and still land at 9%. One caveat on that number. The friction index measures shell interruption and nothing else today, which is why the two everyday modes score the same. The axes where they differ, secret reads and sandbox confinement, are not in the corpus yet."]}),(0,t.jsx)("h2",{className:"font-lora text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"What each mode does not stop"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:["Every mode ships with its residual risk. Prismor OSS prints it straight from ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor mode explain"}),", the same command it runs at install time. This is the reason the feature exists rather than a disclaimer bolted onto it. A posture whose holes you cannot describe is a posture you cannot reason about."]}),(0,t.jsxs)("ul",{className:"list-disc list-inside mb-6 space-y-2 font-lora font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"dev-safe"})," does not stop exfiltration through the channels it allows, and that list is wide. ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"api.github.com"})," is allowlisted by design, so a secret can still reach a public issue comment. It is a control on arbitrary destinations, and it says so."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"trusted-workspace"})," does not stop the code it lets the agent execute. A malicious build script in ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"setup.py"})," or an npm ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"preinstall"})," hook runs with the agent’s full reach. No destination allowlist sees that happen."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"regulated-airgap"})," does not stop its own friction. The realistic failure is somebody running ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor uninstall-hooks"})," to get through an afternoon. Poisoned repository context needs no network either, so local logic manipulation survives the airgap."]})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:["One limit applies to all three. Keeping a secret out of the model’s context is a different job from keeping it out of a tool call, and it needs per-secret enrollment through ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor cloak add"}),". No mode can do that for you."]}),(0,t.jsx)("h2",{className:"font-lora text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-relaxed mb-4 font-lora font-medium text-lg lg:text-xl",children:"A mode is a starting posture. Adopt one, then tighten it once you can see what your agents do."}),(0,t.jsxs)("ul",{className:"list-disc list-inside mb-6 space-y-2 font-lora font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Pick a mode at install time."})," Match it to how much you trust the repository in front of you, which is a question people can answer without reading six config files."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Start in observe."})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor mode apply dev-safe --observe"})," compiles the same posture with nothing blocking, so you get a week of evidence before anything interrupts a developer."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Read the residual risk before adopting."})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor mode explain"})," names the gaps. If a listed gap is the one your threat model cares about, that mode is the wrong starting point."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check the runtime for dev-safe."})," Its sandbox enforces, so it needs Docker. Without a runtime the apply refuses rather than degrading into a weaker posture nobody would notice."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Re-check for drift."})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor mode show"})," reports the active mode and how far the file has moved from it."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-relaxed mb-6 font-lora font-medium text-lg lg:text-xl",children:"Any control with six independent axes has a configuration surface, and a configuration surface is somewhere a policy can be wrong while looking right. Named postures that publish their own trade-offs turn that surface into something you can audit in one command, which is the whole bet behind shipping this as part of Prismor OSS. So here is the question worth putting to any agent control plane you are weighing up: can it tell you, right now, what it is letting through?"})]})},{id:"agent-org-context-drift",title:"The Definition of a Wrong Agent Action Depen
1ds on Org Context That Drifts",description:"The same tool call is routine in one organization and reportable in another. Judging an agent action needs a live model of the org, and that model moves every week.",date:"September 1, 2026",category:"Agent Security",ogImage:"/blog/agent-org-context-drift-2026-09-01-hero.png",ogImageAlt:"Title card reading context drift is an ontology problem, judging agent actions needs a live org ontology.",coverFit:"cover",keywords:["agent context drift","org ontology AI agents","AI agent policy enforcement","knowledge graph agent security","agent governance drift detection","shadow AI MCP server discovery","session scoping AI agents","data class destination policy","tool call authorization","agent instance identity","AI use case risk tier","context engineering vs org model","narrow agent blast radius","AI agent control plane","agent security ontology"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Seven years of retrieval work teaches a particular lesson. Search ranking, entity resolution, query understanding, and long stretches of travel data where the same hotel arrives under eleven names and three of them are wrong."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The fix was an ontology: decide what a property is, what a rate plan is, which relationships are allowed to exist, then make every downstream system answer to that shape. Knowledge graphs did the work much better than vector similarity over similar text."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The habit persists outside work. An"," ",(0,t.jsx)("a",{href:"https://github.com/Ar9av/obsidian-wiki",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Obsidian wiki repo"})," ","can hold personal memory as linked pages with typed edges, because a chat log only replays what was said and a vector index only returns what looks close. You maintain ground truth by hand or it rots while you keep querying it."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"So the industry rediscovering ontologies last year was welcome news. Then the same techniques met security for AI agents, and one question turned out to be beyond what those graphs could answer."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"‘Wrong’ is not a property of the action"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"When someone tells you an agent went wrong, ask what they compared it against."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["At a four-person startup, reading that file,"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:'read_file("contracts/q3-renewal.pdf")'}),", might be completely normal. At an insurer, the exact same action could trigger a compliance and reporting obligation."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The verdict comes out of a relationship: this subject, holding these entitlements, touching a document at that tier, inside a use case approved at that risk level, on behalf of an owner who may or may not still work there. Change any one of those and the same bytes flip from routine to reportable."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/agent-org-context-drift-2026-09-01-verdict.png",alt:"One tool call routed through two organizations. Org A allows it, Org B denies it, on identical bytes.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"The action is identical. The verdict comes from state the agent never sees."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"It goes both ways in practice. A block that reads as paranoid in one org is the only thing standing between another org and a fine worth four percent of revenue. A summarization agent touching internal memos is boring. The same agent pointed at a multi-million contract, translating a clause into another language, is a legal exposure with a named owner."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Security for agents turns out to be an ontology question wearing a different hat. You cannot judge an action without the entities and the edges between them."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The named layers all model the task"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Every few weeks the agent community names another layer."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"One week it is harness engineering: the execution loop, tool contracts, sandboxing, checkpoints, the boring operating-system work that keeps a long-running agent from falling apart on turn nine."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The next week it is context engineering: assembling what goes into the window on purpose, instead of dumping whatever top-k chunks a vector search handed back."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The
1n someone reminds the room that ontologies never left, and that a bank running 400 applications needs one definition of “customer” that billing, support and compliance all agree on."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Three real layers, and all three are worth building on. Every one of them models the task: what is true in the domain, what belongs in the window, how the loop executes safely. None of them models the organization the task runs inside."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/agent-org-context-drift-2026-09-01-layers.png",alt:"A stack of semantic, context and harness layers bracketed as the task, sitting over the model, with the org drawn as a separate dashed box outside the stack.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Three named layers, all modelling the task. The organization sits outside every one of them."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The org model is stateful"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"People file the organizational picture as a policy PDF. It behaves like live state, and it moves:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"which data classes exist and where they sit"}),(0,t.jsx)("li",{children:"which permissions a user actually holds, including the low-level entitlements nobody remembers granting"}),(0,t.jsx)("li",{children:"which use cases got approved, at what risk tier, with which model version"}),(0,t.jsx)("li",{children:"who is accountable when the output is wrong"}),(0,t.jsx)("li",{children:"which agents and MCP servers somebody installed last Thursday"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Each of those changes without anyone telling the agent. Someone gets added to a shared drive. A model gets swapped for a cheaper one. A use case that shipped as summarization quietly grows into reasoning. Legal signs off on a new region."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"A hotel ontology holds still for months. An org ontology holds still for about a week. That is the difference retrieval work tends to underestimate: modelling the entities is the solved part, and there is no machinery for the fact that the model itself keeps moving under the agent."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Drift is two clocks disagreeing"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Most drift talk points at the model. The version that keeps showing up runs the other way: the org moves and the agent’s copy does not."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Picture an agent making investment calls off market data, open-source intelligence and your own portfolio. You did the work: access control, prompt hardening, data protection, a signed-off model. Then someone manipulates one upstream data source. Every control still passes, the output moves, and your investment pattern moves with it."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"You catch that only if you kept a picture of normal for this org and kept checking the live one against it."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/agent-org-context-drift-2026-09-01-drift.png",alt:"Two timelines labelled org and agent. The org line advances through several events while the agent line stays flat, and the vertical gap between them is labelled drift.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Neither clock is wrong on its own, but the gap between them is a signal."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Neither clock is wrong on its own. The gap between them is the signal, and you can only compute a gap if both sides are written down somewhere outside the model. So the ontology work comes before the monitoring work. You cannot diff two pictures of an organization until you have decided what an organization is made of."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Where this lands in code"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This is the part Prismor builds. One graph of the organization, and every enforcement point reads from it."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The entities are the boring ones you would draw on a whiteboard: a device, a session, a tool, a data class, a destination, a subject carrying a permission profile. Plus a named agent instance, which is a different thing from a framework, so support-bot and release-bot can share a runtime and carry different c
1ontrols."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The edges are where the judgment lives."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Tools carry tags, and tags compose into paths through a session."," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"untrusted_content then private_data then external_comms -> block"})," ","reads as an ordered path. Swap"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"then"})," ","for"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"with"})," ","and it means co-occurrence instead of sequence. Neither one is expressible as a regex over a command line, which is why a flat rule table kept missing it."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A data class crossed with a destination tier decides what may leave. One engine asks whether a host may be contacted at all, a second asks what may be sent there, and neither half is a finding on its own. Your own email address going to your own staging box stays quiet."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A session gets a subgraph of its own, synthesized once from the task and enforced for every call after that. Anything outside it is denied by omission, which is the property you want and also the one that bites the first time a tool is missing from the list."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"One decision point reads all of it. Coding-agent hooks, an MCP gateway, mirrored built-in tools, in-process SDK adapters, a local evaluation server, a hosted inference-hook channel: six places that discover a tool call, one place that judges it. Six copies of a precedence rule is five too many."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/agent-org-context-drift-2026-09-01-graph.png",alt:"Device, agent and subject nodes feeding a session that produces scope and tags, a data class crossed with a destination, and every edge arriving at a single decision point that fans out to six enforcement surfaces.",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"The entities are dull. The typed edges carry the verdict, and one decision point reads all of it."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Drift then has a definition you can compute. Inventory what is running on the machine, diff it against what the graph says is governed, and the difference is the answer. Same query whether the gap came from an MCP server someone installed on Thursday, a permission that widened, or a use case that grew from summarization into reasoning."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Narrow agents are what make this tractable"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The agents that reach production are microscoped. One job, four tools, a small blast radius. A narrow agent has a subgraph small enough to diff against reality: these tools, these paths, this data class, this subject, this window of time. When the org moves under it, the diff shows up."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A broad agent with the whole toolbelt has nothing to compare against. You cannot detect drift from a baseline you never wrote down."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"So you rarely need to sandbox everything. Scope the agent once per session, write the scope down, then let a deterministic engine check every call against it. The model gets one chance to reason about what this session needs. After that, matching is arithmetic."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What to keep outside the model"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Write the org graph to disk."})," Outside the context window, outside the transcript. If it only lives in the prompt, it is gone by turn twelve."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Resolve scope once per session, enforce it per call."})," Reasoning is slow and probabilistic. Enforcement should be neither."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Attach a name to every use case before go-live."})," Not the IT owner. The person who gets the call when the output is wrong. That name changes what controls peo
1ple are willing to fund."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Log state transitions, not log statements."})," Every tool call, every result, every scope decision, with a timeline you can replay. Your incident responders have never seen an eval harness. Give them something they can read at 2am."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Make the agent check state instead of memory."})," If it already processed that file, it skips because a record says so."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What is left over"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Nobody sells this layer yet. Buy any one AI security product and you have covered a slice: the prompt, the gateway, the endpoint. None of them holds a model of what your own organization currently permits, and none will tell you the day that model changes."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"So write the picture yourself. Take one production agent, put its permitted tools, paths and data classes in a file today, and diff that file against reality next Monday. The lines that come back different are your incident report, three weeks early."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Where this goes"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The Prismor enterprise version addresses it at the scale the problem actually has: one org model spanning every device, agent and session in the fleet, signed policy pushed from a console rather than copied between laptops, and a standing diff between what the graph says is governed and what is really running. The runtime that enforces it is open source at"," ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"github.com/PrismorSec/prismor"}),"."]})]})},{id:"agent-identity-oauth-delegation",title:"Why Agent Identity Needs More Than OAuth Delegation",description:"OAuth assumes a human clicks consent once. Agents act continuously and delegate to each other, a gap MCP auth and new IETF drafts are now racing to close.",date:"August 18, 2026",category:"Agent Security",ogImage:"/blog/agent-identity-oauth-delegation-2026-08-18-iam-flow.png",ogImageAlt:"Flowchart showing an agent tool call for Bash checked against an iam.yaml allow/deny list by the Prismor hook, then blocked or passed on to the policy engine depending on whether Bash is in deny_tools.",keywords:["agent identity management","AI agent authentication","agentic identity","OAuth for AI agents","non-human identity","MCP authentication","Model Context Protocol OAuth","RFC 8693 token exchange","agent delegation chains","AI agent authorization","confused deputy AI agents","workload identity AI agents","IETF agent OAuth draft","AI agent credential sprawl","agent-to-agent authentication"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"In September 2025, a compromised GitHub Copilot coding agent injected a malicious configuration change into a connected Claude Code session, according to a security vendor’s incident writeup published the following year. Two months later, a research-assistant agent, manipulated through content it had been asked to summarize, steered a financial-assistant agent it was connected to into placing unauthorized trades."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"No human approved either action in the moment. Both agents held valid, correctly-issued credentials the whole time. OAuth 2.0 was built for a browser, a person, and one visually-confirmed consent click. An agent runs unattended, calls other agents that call other services, and delegates in chains no single consent screen ever covers."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Where the old model runs out"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["OAuth’s delegation primitive is token exchange, defined in"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"RFC 8693"}),"."," ","One actor trades a subject token for a new token, optionally carrying an"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"act"})," ","claim naming who is acting on whose behalf. It works for one hop. It was not built for the chain human, agent A, agent B, service C."]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"The RFC says so directly."})," A token consumer checks only the top-level claims. It never walks the chain a token traveled."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Earlier hops turn informational."})," A downstream service cannot verify or enforce anything that happened before the most recent hand-off."]}
1),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Natural language hides the caller."})," A tool call phrased in text carries no caller identity the way a typed API call does. A manipulated agent can spend permissions that belonged to a different task entirely."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is the confused deputy problem again: the model acts as both the reasoning engine and the authorization boundary. The two 2025 incidents above show that failure mode running in production."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Six primitives already exist"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Teams building agent identity today are not starting from zero. Six OAuth-adjacent primitives already cover most of the mechanics, and identity platforms are wiring them together specifically for agents:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"On-behalf-of (OBO)."})," Tracks delegation when an agent acts for a human or for another agent."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Token exchange."})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"RFC 8693"})," moves identity and trust across clouds, APIs, and trust domains."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"DPoP."})," Binds an access token to a cryptographic key. A stolen token stops working the moment it leaves the key that issued it."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"PKCE."})," Runs an authorization flow without a stored client secret an attacker could later extract."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"CAEP."})," Reevaluates or revokes access the moment risk conditions change, instead of waiting for a token to expire on its own."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Attribute-based authorization."})," Decides access on claims like user, agent, purpose, task, and context, not on a flat scope string."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Stacked together, those six primitives answer most of the mechanical questions: who issued this token, what key does it require, how fast can it die. None of them answer the harder question a multi-agent chain raises: what was this token actually for, and does that purpose still hold three hops later."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What is actually shipping to close the rest"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MCP moved fastest."})," Its 2025-06-18 revision reclassified"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Model Context Protocol"})," ","servers as resource servers only, ending the earlier setup where a server could act as both authorization server and resource server for the same request."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Resource indicators became mandatory."})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"RFC 8707"})," ","now binds a token to the one server it was issued for. That closes the specific confused-deputy hole and blocks token passthrough. The spec still changes every quarter."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Agent-to-agent auth trails behind."})," Google’s A2A protocol, under the Linux Foundation since mid-2025, reached v1.0 in March 2026 with signed Agent Cards, but it leaves credential acquisition out of scope on purpose."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"The closest IETF draft to standardization is not agent-specific."})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"draft-ietf-oauth-identity-chaining"})," ","sits in the RFC Editor queue as a general cross-domain token-exchange mechanism. It punts on actor chains explicitly."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Everything agent-specific stays fragmented."})," More than a dozen competing individual drafts, from cloud vendors and enterprise identity team
1s alike, each carry a hop count, an immutable originator, or a cryptographically-linked chain of narrowing permissions their own way. None has working-group consensus."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Where OAuth still has to change"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Highly autonomous agents will keep outrunning what token exchange and the six primitives above were designed to handle. Five gaps stand out:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-3 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Delegation chains need to be inspectable, not just chained."})," A reviewer should read who authorized what, at every hop, without reconstructing it from side logs."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Tokens need to carry task purpose and intent, not only scope."})," A scope says an agent can call an API. It says nothing about why, on this task, right now."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Revocation needs to happen in near real time."})," A token that stays valid for minutes after a compromise is detected is a token that already did the damage."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Issuance needs to run at machine speed."})," Human-consent-paced flows do not scale to an agent that spins up sub-agents for a single task and tears them down seconds later."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Multi-agent coordination needs a shared delegation model."})," Point-to-point patches between two agents do not compose once a task touches five."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do now"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The draft landscape will not consolidate before your next agent ships. Build for delegation with what already exists, and track the rest as a moving target."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Inventory agent credentials as their own class."})," A service account issued to an agent carries different risk than one issued to a cron job. Track which agents hold which tokens, issued for what task, for how long."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Prefer short-lived, narrowly-scoped tokens over standing credentials."})," If your identity provider supports token exchange or an equivalent narrowing step per task, use it instead of handing an agent one broad, long-lived grant."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"If you run MCP servers, adopt the 2025-06-18 authorization revision or later."})," Resource-indicator binding alone closes the confused-deputy pattern the earlier spec left open."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Do not treat a valid token as proof of correct intent."})," Both 2025 incidents involved agents that were fully authorized and still did the wrong thing. The compromise happened upstream of the credential, in the content the agent was manipulated by."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Watch identity and enforce independently."})," A credential answers who an agent is allowed to act as. It says nothing about whether one specific tool call, in one specific session, with untrusted input already in context, should be allowed to happen. Prismor’s"," ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"open-source runtime"})," ","enforces that second question at the tool-call boundary itself, session-aware, so a correctly-authenticated agent still gets stopped from turning a summarization task into a trade order."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Agent identity will keep changing under you for years. Build the inventory and the runtime enforcement now, and whichever standard eventually wins becomes one more input to a system you already trust, not the only thing standing between a manipulated agent and the account it holds a token for."})]})}
1,{id:"ai-agent-security-where-controls-attach",title:"Where AI Agent Security Tools Attach, and What Each One Misses",description:"Every AI agent runs the same loop: credentials, context, decision, tool call. Where each category of agent security tool attaches, and what each one misses.",date:"August 12, 2026",category:"Agent Security",keywords:["enterprise AI agent security","AI agent attack surface","AI agent runtime security","agent tool-call enforcement","MCP gateway","AI gateway security","AI agent identity security","non-human identity","AI agent governance","OWASP Agentic Top 10","AI runtime security platform","MCP security","AI agent control plane","prompt injection","coding agent security"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Ask a security team how many AI agents run inside their company and watch the pause. The honest answer comes back as a range, and the range is wide. Agents arrive through a dozen doors: an engineer installs a coding assistant on Tuesday, a product team ships a support bot, somebody wires an internal service to an MCP server over a weekend. Every one of them holds a credential and acts on its own."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Governing them gets awkward fast, because the security stack you already pay for was drawn around a person. Someone signs in, does a bounded set of things, signs out. An agent works nothing like that. It receives its credential once, then runs a loop for hours, pulling in content nobody screened and choosing its next move from whatever it has read so far. Once you look closely at that loop, the whole market for agent security tools becomes much easier to read."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The loop every agent runs"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Strip off the branding and each agent repeats the same handful of moves. It starts with an identity, because someone provisioned a token or a service account, and from that moment the agent carries everything that credential can reach. It takes in context next: your task, plus documents, API responses, pages, and tool output picked up along the way, some of it from places nobody vetted. Then it decides, reading the pile of accumulated context and choosing an action."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Then it acts. A file read, a shell command, a database write, an MCP invocation. This is the tool call, and it is the only move in the whole sequence that touches anything real. The result folds back into context and the loop turns again, twenty times or two hundred, however many the task takes. Off to the side, a log catches fragments."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"One property of that loop drives everything else. Intent sits on one side of the tool call and consequence sits on the other. Before it, the agent is thinking. After it, something already happened."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Every product clamps onto one point on the loop"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The categories on the market today each grab a different moment in that cycle. Their blind spots are not oversights. They follow from where the tool sits."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Identity and credential platforms"})," work at provisioning, before the loop starts. They decide what the agent gets handed, issue it just in time, and pull it back later. During the thousand decisions the agent makes while holding that credential, they have nothing to say."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"AI gateways"})," sit on the model call in the middle of the loop, which buys you routing, request logs, token accounting, and a budget ceiling. They watch the agent think. The file read and the shell command that follow the thinking never pass through them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Runtime detection platforms"})," read the exhaust, matching behavior against injection signatures and anomaly baselines. Their verdict lands after the tool call resolved. On a chain that turns twice a second, an alert is a description of something you can no longer prevent."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MCP gateways"})," attach at the tool call itself, which is the right place, and g
1ive you a server registry, role rules, pre-call checks, and invocation logs. What arrives there is the call on its own, stripped of the reasoning and the earlier context that produced it. A poisoned document read three turns ago yields a request that looks perfectly ordinary by the time it reaches the gateway."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Red teaming and posture tools"})," run the loop in a lab before you ship and surface weaknesses worth fixing. Production runs a different loop, on data the lab never saw."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Line them up and a shape shows through. The moment an agent stops thinking and starts doing carries the thinnest coverage of any point on the loop, and it happens to be the last moment where stopping something is still an option."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"One agent, three places it runs"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A loop-only view flattens a second axis worth keeping. Your company runs that same loop in three different environments, and a control built for one of them cannot see into the others."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"On developer machines."})," Claude Code, Cursor, Codex, and Copilot CLI run beside your source tree, your local credentials, and a live shell."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Inside production services."})," LangChain, CrewAI, and the OpenAI Agents SDK run the loop in process, inside code paths you wrote and deployed."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Across the tool layer."})," Any agent that reaches an MCP server or loads a skill inherits whatever that server or skill can touch."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Most governance projects pick one environment and call the job done. A rule that keeps a developer’s coding agent away from production, while the LangChain service behind your API reaches it freely, is a rule with a hole shaped exactly like your production traffic."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor approaches it"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Prismor puts its control at the tool call and runs one policy across all three environments. For coding agents, it hooks the tool execution cycle, so a call gets evaluated on the way out instead of described afterward. For production frameworks, an in-process adapter wraps the framework’s own tool execution with that same engine, so a single rule covers an engineer’s laptop and the pipeline serving your customers. At the tool layer, an MCP gateway consolidates downstream servers behind one enforcement point with pre-call checks and complete invocation logs. Policies live in version control and get pulled like any other configuration."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Sitting at the call with the session’s history in hand opens up a few things a single-point tool cannot reach."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Combination rules."})," The engine remembers what a session already touched, so it can stop the pattern where an agent reads untrusted content and then reaches for a shell, catching it before that second call executes."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Step-up approval."})," Production writes, outbound calls, and code pushes halt the loop and wait for a person to say yes."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Supply chain checks."})," Skills and MCP servers get matched against known-vulnerability data, with typosquat detection and schema-drift monitoring that catches a server changing shape under you, plus a sweep for agents and servers nobody registered."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Signed audit."})," Each action ties back to a named agent and the human it answers to, in a tamper-evident trail that yields evidence an auditor accepts."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Mapped back onto the loop, that reaches every point on it: the credential at the start, the context and combinations through the middle, enforcement at the call itself, and a record at the end that somebody can read six months later."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Count before you buy"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Write down every coding agent on every developer machine, every agent running inside a production service, and every MCP server and skill any of them can reach, each one tied to the human or service it answers to. Teams that do this usually find the list runs longer than expected and that nobody owns a third of it. Every control you pick afterward 
1is guesswork until that list exists."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Then put a single question to whatever you are evaluating. When an agent reaches for something it should never touch, does this stop the call, or does it tell me afterward? Both answers have a place in a security program. Only one of them changes what happens next."})]})},{id:"trustworthy-ai-control-plane-for-enterprises",title:"How to Build a Trustworthy AI Control Plane for Enterprises",description:"Blueprint for a trustworthy enterprise AI control plane: agent inventory, runtime enforcement at the tool-call boundary, a signed audit trail, and policy tiered to autonomy.",date:"July 31, 2026",category:"AI Governance",ogImage:"/blog/trustworthy-ai-control-plane-2026-07-31-diagram.png",ogImageAlt:"Diagram of the Prismor control plane: developer agent interfaces on the left, a policy/audit/dashboard cloud on top, the Prismor Gate in the middle, and tools (database, external API, file system) on the right.",keywords:["AI control plane","trustworthy AI control plane","enterprise AI governance","AI agent inventory","runtime enforcement AI agents","tool-call boundary security","signed audit trail AI agents","Ed25519 audit trail","AI agent policy enforcement","MCP gateway security","ISO 42001 compliance","NIST AI RMF","OWASP Agentic Top 10","AI agent identity","policy as code AI agents"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Enterprises are past the question of whether to deploy AI agents. The live question is how to keep thousands of them inside the lines. That is 
1what a control plane does: it gives a security team central visibility, policy enforcement at runtime, and proof of what every agent did on whose behalf. Building one is an engineering project, and a few early decisions determine whether it holds under real conditions."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The tempting shortcut is to buy your cloud provider’s version and map each control to a service you already run. Identity becomes their IAM. Audit becomes their cloud trail. Guardrails become a feature of their model platform. It reads clean in an RFP and satisfies the control taxonomy. It also governs a single boundary: the traffic that crosses that one platform. Enterprise agents work past that boundary all day. A coding agent on a developer laptop runs a shell command against the local filesystem. A research agent calls three third-party SaaS tools and a self-hosted MCP server inside one session. Those actions generate no event the platform can read. A control plane worth trusting has to reach the place where the agent acts, and that single requirement drives every build decision below."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Start with an inventory"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The first thing an auditor or an incident responder asks is how many agents you run and what tools each one can reach. Most enterprises cannot answer. That gap is where you begin, because every control downstream of it is guesswork until it closes."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Build a registry that names every agent in the estate: the coding agents on engineer machines, the framework agents in production services, the embedded assistants inside SaaS you bought. For each one, record the tools and MCP servers it can call and the human or service identity it acts for. Agents that register their tool roster at startup keep this list current instead of letting it rot into a stale spreadsheet. An inventory sounds like table stakes, and it is the control most organizations skip. When “the AI did it” is the only answer available after an incident, you have a governance program on paper and no control in fact."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Put the gate where the agent acts"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The decision that shapes the whole build is where enforcement runs. An agent can be watched at four boundaries, and each one sees a different slice of what the agent does. A reverse-proxy gateway sits between the agent and remote APIs. It reads full payloads and binds corporate identity well, and it goes dark on any local shell command, because that command never touches the network. A kernel sensor sits at the system-call layer. It resists tampering and cannot be switched off from an app config, and it reads a stream of syscalls where a malicious sequence looks much like a legitimate build. An out-of-band scanner polls cloud and SaaS APIs on a schedule. It covers everything it can reach through OAuth and reports posture after the session has already ended."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The boundary that holds for enterprise coding and framework agents is the runtime hook: a gate inside the agent’s execution loop, ahead of the tool. It reads the action before the process spawns, which is the position from which you block a destructive command rather than log it afterward. It sees the local shell, the file write, the package install, and the agent’s intent for the call. A gate this close to the call has to stay fast enough that teams never feel pressure to bypass it, so blocking a dangerous action stays viable instead of arriving too late to matter."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Two properties make the gate trustworthy under pressure. It has to carry session state, so it knows an agent already read untrusted content before it evaluates that agent’s next write-and-send. An agent that can read untrusted input, write to disk, and reach the network holds three permissions that each pass review alone and form an exfiltration path together. A gate that inspects one call at a time approves all three and misses the combination. The gate also has to survive streaming, because agent frameworks stream partial responses by default and any control that fires only on a complete response fails open under load."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Make trust provable"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Most governance stacks ask a reviewer to trust a log. An append-only file states that an agent called a function. In a dispute that is a weak artifact. An engineer who says the agent “only upgraded one library” and a log that says the same thing carry equal weight, which falls short of what an auditor in a regulated industry accepts."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Build the audit trail so it proves behavior on its own. Sign each action with a per-device key over a hash of the action, the agent identity, and a timestamp, then chain each receipt to the one before it. Now the record shows that this agent, on this enrolled device, took this action at this time, in a sequence no one edited after the fact. An ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Ed25519"}),"-signed chain answers the accountability controls in ISO/IEC 42001 and the OWASP Agentic Top 10 with evidence a reviewer can verify."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This property earns its cost the moment your estate spans more than one platform. With a hosted model, a self-hosted model, a laptop coding agent, and a partner’s SaaS all in play, no single provider’s trail covers the full path an action traveled. Signed execution records travel with the agent, so proof follows the workload across providers rather than living inside any one of them. Handle secrets the same way: cloak a credential into an opaque token before it reaches the model, and the agent never holds the real value to leak in the first place."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Match the rigor to the autonomy"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Running one control level across every agent creates friction where it is too heavy and exposure where it is too light. Scope the rigor to how much the agent can do on its own. A read-only assistant that summarizes documents needs guardrails on what it can see. An agent that modifies production configuration needs a gate on every state-changing call. The dividing line is decision authority: an agent that can change state without a human approving that specific action sits at a higher autonomy tier and earns heavier controls, whatever the procurement paperwork called 
1it."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The policy itself should compose in layers that resolve at the same gate: an org-wide floor no team can drop below, team and per-user rules on top, and per-session scope for the task at hand. Adjusting a user’s policy should take a config change and never a redeploy. Roll enforcement out the way buyers accept it, starting in observe mode so teams see what would have been blocked before you switch any rule to enforce. Give escalation real positions: step up and wait for approval, defer into an async review queue, or deny outright, and fail closed when the approval path is unreachable."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Build the control plane this way and compliance falls out of the engineering instead of running beside it. The controls that satisfy ISO 42001, NIST AI RMF, and the OWASP Agentic Top 10 are the same controls that stop a real incident."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Build the inventory first."})," Name every agent, its tools and MCP servers, and the identity it acts for, before adding any other control on top."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Enforce at the runtime hook."})," Put the gate inside the agent’s execution loop, ahead of the tool call, where session state and streaming responses are both visible."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Sign and chain the audit trail."})," A per-device signature over each action, chained to the one before it, turns a log into evidence instead of an assertion."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Cloak secrets before the model sees them."})," An opaque token in place of the real credential removes the leak path at its source."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Scale rigor to autonomy."})," Layer org, team, and session policy at one gate, start new rules in observe mode, and fail closed when an escalation path is unreachable."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Look at a working implementation."})," Prismor’s ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"open-source runtime"})," ships the inventory registration, the runtime hook, and the signed audit chain described above, so you can read the enforcement path directly instead of taking it on faith."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Organizations that pass AI governance audits built these into the runtime. The ones that struggle wrote them into a policy document and hoped. An agent that can prove what it did earns the room to do more, and that is the whole point of the plane you are building. Start with the inventory, put the gate where the agent acts, and make the record provable, and you can extend autonomy across your estate with evidence behind every grant of it."})]})},{id:"hugging-face-autonomous-ai-agent-breach-glm",title:"Hugging Face Was Breached by an Autonomous AI Agent, Then Had to Use an Open-Weight Model to Investigate It",description:"An autonomous AI agent breached Hugging Face on July 16, 2026, running 17,000+ actions across disposable sandboxes. Frontier model APIs refused to help analyze the attack logs, so Hugging Face ran forensics on GLM 5.2 on its own GPUs instead.",date:"July 22, 2026",category:"Incident Analysis",ogImage:"/blog/hugging-face-autonomous-ai-agent-breach-2026-07-22-attack.png",ogImageAlt:"Diagram showing a malicious dataset auto-processed by Hugging Face, hidden code opening a backdoor, and an autonomous AI hacker bot scanning systems, creating sandboxes, and stealing tokens across internal 
1clusters.",keywords:["Hugging Face security breach","autonomous AI agent attack","Hugging Face July 2026 incident","AI powered cyberattack","GLM 5.2 forensic analysis","open-weight model incident response","dataset remote code execution","template injection dataset loader","AI agent credential theft","self-hosted LLM security analysis","commercial API guardrail refusal","agentic AI attack surface","AI incident response guardrails","swarm of sandboxes attack","Prismor agent security"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"On July 16, 2026, Hugging Face disclosed that an autonomous AI agent had breached its production infrastructure. The attacker’s own action log ran past 17,000 recorded events, generated over a single weekend without a human operator directing any of them."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["Hugging Face’s own anomaly detection pipeline caught the intrusion, using LLM-based triage to correlate ",(0,t.jsx)("a",{href:"/ai-agent-observability",className:"text-amber-700 underline hover:text-amber-900",children:"security telemetry"}),". Its team found no evidence that public models, datasets, or Spaces had been tampered with, and verified the software supply chain clean. Then it hit a second problem: the tools built to analyze the attack kept refusing to look at it."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the attack worked"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The entry point was a malicious dataset. Hugging Face’s dataset processing pipeline chained two code-execution paths: a remote-code dataset loader and a template injection in dataset configuration. When the platform’s automated systems opened the dataset to process it, both flaws fired, and the attacker got code execution on a processing worker."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"From there the agent escalated to node-level access, harvested cloud and cluster credentials, and moved laterally into several internal clusters. It ran thousands of individual actions across what Hugging Face described as a swarm of short-lived sandboxes, staging command-and-control on public services and migrating between disposable environments as it went. A human operator or a static exploit tool executes a fixed plan. This agent re-planned after every action, which is what let it run unattended for a full weekend."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Hugging Face has not identified the specific model that powered the attack. The attacker accessed a limited set of internal datasets and several credentials used by Hugging Face services. At disclosure, Hugging Face was still assessing whether partner or customer data had been affected."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why the investigation stalled on commercial APIs"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"With 17,000-plus actions to sort through, Hugging Face’s incident responders reached for frontier models through commercial APIs to accelerate triage, the same way any team would reach for an LLM to summarize a large volume of structured logs. The analysis required feeding those models real attack commands, exploit payloads, and command-and-control artifacts pulled directly from the compromise. The providers’ safety guardrails blocked it."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The guardrails could not distinguish an incident responder analyzing a completed attack from an attacker planning a new one. A content filter reads exploit code as exploit code, regardless of who is holding it or why. Hugging Face ran its forensic analysis on ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"GLM 5.2"})," instead, an open-weight model from Z.ai, hosted on its own GPUs. The switch solved two problems at once: a model that would read the logs, and a guarantee that attack data and credentials never left Hugging Face’s environment."]}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog/hugging-face-autonomous-ai-agent-breach-2026-07-22-response.png",alt:"Diagram showing Hugging Face's security team facing 17,000+ action logs, a commercial AI model refusing to analyze the attack, and a self-hosted GLM 5.2 model on their own GPUs successfully analyzing the full attack, followed by incident response steps and authorities being notified",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"The commercial model refused the logs. The self-hosted one read all of them."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The asymmetry this exposes"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The attacking agent operated under no usage policy. It read its own exploit payloads, reasoned about them, and acted on them without a content filter slowing it down. The defenders, using the same category of tool for the opposite purpose, hit a wall built for a different job: stopping a model from helping someone write malware. Understanding malware that already ran is a separate task, and the guardrails were not built for it."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Security team
1s have complained for years that commercial AI tools are tuned for the median consumer, not for security work. Here that gap cost real time during an active incident response, at one of the largest AI infrastructure providers in the world, against an attacker that itself ran on AI. The side with fewer constraints moved faster than the side with more of them."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What is affected"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Hugging Face internal infrastructure:"})," the attacker accessed a limited set of internal datasets and several service credentials."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Public-facing assets:"})," Hugging Face found no tampering with public models, datasets, or Spaces, and verified its container images and packages clean."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Users:"})," Hugging Face advised rotating access tokens and reviewing account activity while its credential-impact assessment continued."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Hugging Face closed the exploited code-execution paths, rebuilt compromised nodes, and rotated affected credentials. It also deployed stricter admission controls and moved to faster, always-on alerting. Those steps address this breach. A harder problem sits upstream of any single fix."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Treat any pipeline that auto-processes untrusted uploads as a code-execution surface."})," A dataset can run code the moment something in your stack parses or loads it, the same as a package or a container image."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Build your incident response tooling before an incident, not during one."})," Discovering that your forensic AI tooling refuses to read exploit logs at the moment you need it most is an ",(0,t.jsx)("a",{href:"/ai-agent-governance",className:"text-amber-700 underline hover:text-amber-900",children:"agent governance"})," failure, not a model limitation."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Keep an on-premises or self-hosted analysis path available for sensitive investigations."})," It avoids guardrail refusals and keeps attacker artifacts and internal credentials from transiting a third party during an active compromise."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Plan for agentic attackers now."})," An agent that re-plans after every action and spreads itself across disposable sandboxes moves at a pace and a scale manual detection was never built to match."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Infrastructure gets breached; that part is not new. The tooling gap between attacker and defender is, and it is widening in the attacker’s favor because both sides are automating. Teams preparing for the next incident like this should treat AI-assisted forensics as core incident response infrastructure, with its own uptime and access guarantees, rather than something bolted on from whichever commercial API happens to be convenient."})]})},{id:"eu-ai-act-what-it-means-for-your-business",title:"The EU AI Act Is in Motion: Scope, Timelines, and What Your Team Actually Has to Do",description:"The EU AI Act regulates AI by risk tier, reaches any system that touches EU users, and fines up to 7% of global revenue. The deadlines and the team-by-team work.",date:"July 15, 2026",category:"AI Governance",keywords:["EU AI Act","EU AI Act compliance","EU AI Act timeline 2027","Digital Omnibus AI","high-risk AI systems","prohibited AI practices","AI transparency obligations","AI Act extraterritorial scope","Regulation EU 2024/1689","AI Act fines 7 percent","AI inventory shadow AI","human in the loop AI","AI content watermarking","AI deployer obligations","AI governance"],faq:[{question:"Does the EU AI Act apply to companies outside the EU?",answer:"Yes. The Act is extraterritorial. If your AI system is available to users in the EU, or if your model’s outputs affect people living there, you are bound by it regardless of where your company is headquartered. A US startup that screens EU-based job applicants carries the same obligations as an EU company."},{question:"When do EU AI Act rules take effect?",answer:"The Act entered into force in August 2024 and phases in over several years. Bans on prohibited practices applied from February 2025, general-purpose AI model obligations from August 2025, and transparency rules for chatbots and synthetic content apply from August 2026. Most high-risk system obligations were deferred by the Digital Omnibus on AI to late 2027."},{question:"What are the risk tiers in the EU AI Act?",answer:"The Act sorts AI into four tiers by potential harm. Prohibited uses such as social scoring and non-consensual intimate deepfakes are banned. High-risk systems used for hiring, credit, healthcare, and law enforcement require documentation, logging, and human oversight. Limited-risk systems such as chatbots must disclose AI use and mark synthetic media. Minimal-risk systems carry no new obligations."},{question:"What are the penalties for violating the EU AI Act?",answer:"Deploying a prohibited AI system can cost up to 35 million euros or 7% of global annual turnover, whichever is higher. Other violations carry lower but still significant caps tied to company revenue."},{question:"What should companies do now to prepare for the EU AI Act?",answer:"Map every AI asset in use, including third-party tools and unauthorized shadow AI. Classify each system into a risk tier to learn which obligations apply. Begin documenting training data, testing, and safety guardrails for high-risk and transparency-bound systems, and place human review and audit logging at the point where a model turns a decision into a real-world action."}],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A SaaS startup in Chicago screens EU-based job applicants with a model it fine-tuned last quarter. Its founders assume EU law stops at the EU border. It does not. Under the AI Act, that startup carries the same obligations as a software house in Munich, because the Act follows where the AI reaches, not where the company is headquartered."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The EU AI Act is the first comprehensive, legally binding framework for artificial intelligence, and it is already phasing in. It works the way the GDPR did: if your system touches people inside the EU, you comply. The good news for most teams is that the rules are specific enough to plan against. The hard part is that the work spans legal, product, engineering, data, and security at the same time."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The risk tiers, and what each one demands"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The Act does not regulate AI as one thing. It sorts applications by how much harm they can cause, and the obligations scale with that. Four tiers matter for planning."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Prohibited."})," Some uses are off the table. Cognitive manipulation that causes harm, government social scoring, untargeted scraping for facial-recognition databases, and certain real-time biometric surveillance. The banned list now also covers “nudifier” tools that generate non-consensual intimate deepfakes."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"High-risk."})," AI used for life-altering decisions: hiring, education, credit, healthcare, critical infrastru
1cture, law enforcement. These are allowed, and they carry the heaviest load. Detailed technical documentation, data governance, event logging, risk management, and real human oversight."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Limited risk."})," Chatbots and generative tools. You have to tell people they are dealing with a machine, and AI-generated media such as deepfakes has to be marked as synthetic in a machine-readable way."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Minimal risk."})," Spam filters, recommendation features, most everyday AI. No new obligations, though the transparency habits above are worth adopting anyway."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The timeline, including the 2027 shift"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The Act entered into force in August 2024 and applies in waves rather than all at once. The dates that shape most roadmaps:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"February 2025."})," The bans on prohibited practices took effect, along with AI-literacy duties for staff who build or operate these systems."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"August 2025."})," Obligations for general-purpose AI models began, overseen by the new European AI Office."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"August 2026."})," The transparency duties for limited-risk systems apply. Chatbots must disclose that a user is dealing with a machine, and AI-generated media has to be marked as synthetic. If you ship a chatbot or a generator, this is the near-term deadline."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Late 2027."})," High-risk systems were originally due mid-2026. A legislative update, the “Digital Omnibus on AI,” deferred most of that deadline to late 2027 to give teams room to prepare. The extra time is for building, not for waiting."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why non-EU companies are already in scope"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The Act is extraterritorial. If your software is available to users in the EU, or if your model’s outputs affect people living there, you are bound by it regardless of where you sit. This is the GDPR pattern, and it caught plenty of teams off guard the first time."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The penalties are sized to get attention. Deploying a prohibited system can cost up to €35 million or 7% of global annual turnover, whichever is higher. Other violations carry lower but still serious caps. For a company with real revenue, this is a board-level number, not a line item."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The work is cross-functional, so split it by team"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Hand the whole Act to legal and they drown in code repositories. Hand it to engineering and they drown in legal text. Compliance here is a team sport, and each group owns a distinct piece."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Legal and compliance."})," Build the AI inventory, including shadow AI that staff adopted without asking. Classify each system into a tier, handle filings and policy, and verify that any third-party model you deploy is compliant, since the deployer stays liable."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Product."})," Own transparency and oversight in the interface. Make it obvious when a user is talking to a machine, mark synthetic media, and design clear paths for a human to review, intervene, or override an automated decision such as a rejected credit application."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Engineering."})," Build the guardrails. Tamper-resistant logging that can reconstruct why a model made a given decision, plus a rehearsed way to disable or roll back a model that starts drifting or producing unsafe output."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Data science."})," Own data hygiene. Document where training data came from and how it was filtered, confirm the datasets are representative, and audit models for demographic or historical bias before they ship into hiring or scoring."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Security and IT."})," Govern the identity of the AI itself. Treat autonomous agents like accounts with scoped, restricted tokens, monitor what they can reach, and keep the regulator-facing logs encrypted and isolated from tampering."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The deadlines roll out in phases, so the useful move now is to know y
1our exposure before the clock runs down."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Map your AI assets."})," List every model, feature, and third-party integration in use, including the tools employees adopted on their own."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Classify each system."})," Place it on the tier scale. That single answer tells you which obligations apply and how much time you have."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Start the paper trail."})," For anything high-risk or transparency-bound, begin documenting training data, testing, and safety guardrails now rather than reconstructing it under a deadline."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Put oversight where actions happen."})," Human review and audit logging matter most at the point a model turns a decision into a real-world action, so build the enforcement there."]})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The open era of shipping AI with no rulebook is closing, and the teams that treat governance as an engineering property will spend late 2027 shipping instead of scrambling. You can read the binding text in ",(0,t.jsx)("a",{href:"https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32024R1689",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Regulation (EU) 2024/1689"}
1),". The real question is narrower than the law: do you know, today, which of your systems would land in the high-risk tier?"]})]})},{id:"agent-governance-optimization-problem",title:"Beyond the Binary: Why Agent Governance Is an Optimization Problem",description:"Agent governance should maximize the value of autonomous work within a dynamic risk threshold, rather than rely on static binary controls.",date:"July 14, 2026",category:"Agent Security",keywords:["agent governance optimization","AI agent risk management","dynamic risk boundaries","AI agent access control","agentic workflow governance","prompt injection attack surface","AI agent RBAC","agent sandbox security","human in the loop alert fatigue","multi-agent validation security","agent action risk assessment","AI agent runtime policy","AI agent execution boundary","Prismor agent governance"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"An autonomous agent can update a database schema, generate a complex WebGL environment, or coordinate a release workflow. The same access that makes those jobs useful can also let the agent change production state, expose sensitive data, or confidently break a build. Teams encounter the tension quickly: capability and control are coupled."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Static roles, firewalls, and zero-trust rules remain necessary foundations. They do not give teams a complete answer for an agent whose proposed action changes with its task, context, tools, and data. Blanket blocks remove the autonomy that made the workflow worthwhile. Agent governance needs to decide which actions are acceptable at the moment they are proposed."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The real attack surface is the workflow"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"An agent is an LLM running in a loop with an objective, a harness, a context window, and a set of tools. Its security posture emerges from that whole system. The model provider matters, but so do the instructions that shape the task, the permissions behind each tool, the sources that feed context, and the execution environment where a decision becomes an action."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That context is a large and changing attack surface. Teams routinely pass agents markdown, code comments, tickets, documents, web content, and image alt text. Each source can carry hostile instructions that look like ordinary data. An agent parsing external assets for a 3D scene, for example, could encounter injected directions to alter its output or move sensitive context to an external destination. Legacy controls often miss this path because the request can look valid at the network and identity layers."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why familiar controls fall short on their own"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Several common patterns help in narrow situations, then fail when they become the only control. The gap is real wherever a probabilistic system is connected to data and execution layers."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Human approval can become habituation."})," Repeated approval requests for complex, multi-step work create alert fatigue. A reviewer who cannot quickly reconstruct the intent, scope, and consequence of an action is likely to turn approval into a rubber stamp."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Sandboxes eventually need doors."})," Isolation is valuable, but useful agents often need data, tools, and execution paths outside a read-only environment. Every necessary exception changes the real boundary, which is why narrowly defined enterprise workflows are easier to govern than open-ended agents."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Agent validation remains probabilistic."})," A second agent can offer a useful signal about a runner agent’s output. It cannot serve as the final enforcement point. Stochastic reviewers introduce their own non-determinism and can leave teams detached from what their systems did."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Governance is a constrained optimization loop"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The practical objective is to maximize the expected value of an agent action while keeping its real-time risk inside the tolerance for the environment:"}),(0,t.jsxs)("div",{className:"mb-6 rounded-lg border border-amber-200 bg-amber-50 px-5 py-4 text-center text-base text-amber-950 sm:text-lg",children:["max E[V(A",(0,t.jsx)("sub",{children:"t"})," | C)] subject to R(A",(0,t.jsx)("sub",{children:"t"}),") ≤ τ"]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:["Expected value, V(A",(0,t.jsx)("sub",{children:"t"})," | C)."]})," The benefit of the proposed action at time ",(0,t.jsx)("em",{children:"t"}),", given the agent’s capabilities and the task context."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:["Real-time risk, R(A",(0,t.jsx)("sub",{children:"t"}),")."]})," The action’s exposure after considering its target, arguments, source data, identity, destination, side effects, and the broader workflow state."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Risk threshold, τ."})," A boundary that changes with the environment. A low-impact draft may tolerate more autonomy than a production database migration or an outbound transfer of customer data."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This changes the governing question from “Does this agent have permission?” to “Should this exact action be allowed now?” The answer can still include explicit roles and trusted identities. It also evaluates intent and context where they matter: at the tool-call boundary, before a command, API request, or write operation runs."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Keep engineering comprehension in the loop"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The hardest failure mode is the delegation trap. A team can hand work to an agent and gradually hand away its understanding of the architecture, data flows, privileges, and failure paths. No optimization function, approval queue, or scanner can compensate for a team that cannot explain what the agent is allowed to change and why."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Agents are execution tools. They can accelerate complex full-stack work, but engineers still own the system they operate. That ownership means understanding which tools exist, which credentials they use, what data is untrusted, and which actions have irreversible consequences."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Start with the agent’s action path. The goal is to preserve useful autonomy while making each sensitive step explainable, bounded, and enforceable."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Map the full workflow."})," Inventory the agent’s context sources, tools, credentials, destinations, and possible side effects. Treat external 
1content and tool responses as untrusted inputs."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Classify actions by consequence."})," Separate drafting and read-only work from writes, schema changes, credential access, network egress, and production changes. Give each class an explicit risk threshold."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Evaluate exact arguments at runtime."})," Inspect the command, API method, resource, destination, and user or session context before execution. A role alone cannot capture the full meaning of a proposed action."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Use human review deliberately."})," Reserve approval for decisions that need judgment and give reviewers a concise explanation of scope, impact, and rollback. Avoid approval prompts that ask people to validate opaque chains of work."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Maintain an action-level audit trail."})," Record the agent, initiating user, policy, inputs, tool arguments, decision, and outcome so teams can tune the boundary against real workflows."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Strong agent governance gives teams a way to use capable systems without granting unbounded authority. The right constraint is dynamic, rooted in the action and its context, and backed by an enforcement point outside the model. That is how autonomy becomes an engineering advantage that a team can understand, audit, and control."})]})},{id:"ai-soc-execution-boundary-agentic-security-2026",title:"AI SOCs Need an Execution Boundary Before They Gain Autonomy",description:"AI SOC agents can investigate across SIEM, EDR, IAM, and cloud tools. Their actions need a policy decision at every execution boundary.",date:"July 10, 2026",category:"Agent Security",ogImage:"https://d205xtizsu1yjh.cloudfront.net/blog/ai-soc-2026-07-10-og.webp",ogImageAlt:"Diagram showing an AI SOC agent exchanging context with SIEM, EDR, IAM, and cloud systems, with an analyst supervising alerts and response.",keywords:["AI SOC security","agentic SOC","AI security operations center","SOC agent security","AI agent execution boundary","security operations AI agents","AI SOC governance","SOC agent authorization","AI incident response guardrails","SIEM EDR IAM AI agent","MCP security operations","AI agent tool-call security","NIST AI agent security","MITRE ATLAS","Prismor agent security"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The AI SOC has moved from a product roadmap concept to a working operating model. ",(0,t.jsx)("a",{href:"https://cloud.google.com/solutions/security/agentic-soc",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Google Security Operations now describes agents that triage alerts, investigate threats, hunt for activity, and help drive remediation flows"}),". That is real leverage for a team buried under alert volume. It also gives an agent a path into the systems that describe and change an environment."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["A security agent can collect endpoint context from an ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"EDR"}),", search a ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"SIEM"}),", inspect identity data, query cloud posture, and open or close a case. If that same workflow can disable an account, isolate an endpoint, rotate a credential, or alter a detection rule, the question is no longer whether the investigation was useful. The question is whether each proposed action should be allowed in this session, for this tenant, with these arguments."]}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"https://d205xtizsu1yjh.cloudfront.net/blog/ai-soc-2026-07-10.webp",alt:"Diagram showing an AI SOC agent exch
1anging context with SIEM, EDR, IAM, and cloud systems, with an analyst supervising alerts and response",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"An AI SOC turns security context into tool calls. Each call needs a clear authority, a narrow scope, and an auditable decision."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The AI SOC is an execution system"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The useful part of an agentic SOC is its ability to work across disconnected evidence. Google’s Triage and Investigation agent, for example, is designed to gather evidence, perform analysis, correlate signals, and return a verdict. Its security operations materials also describe ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"})," support for connections across an organization’s IT and security environment. That is exactly the shape teams want: an analyst asks a question once and receives a finished investigation instead of a pile of tabs."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"It is also a meaningful expansion of the trust boundary. A traditional correlation rule follows a defined query and a defined playbook. An agent interprets evidence, chooses tools, selects arguments, and may sequence several steps before it reaches a conclusion. Alerts, ticket text, email artifacts, threat-intelligence records, and tool responses can all carry untrusted content. Once an agent can translate that content into a privileged API call, it has become part of the incident-response execution path."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why identity alone does not answer the decision"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["NIST has put the issue plainly. Its ",(0,t.jsx)("a",{href:"https://www.nist.gov/news-events/news/2026/01/caisi-issues-request-information-about-securing-ai-agent-systems",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"January 2026 request for input on securing AI agents"})," calls out risks from adversarial data, insecure models, and harmful actions, then asks how deployers can constrain and monitor the extent of agent access in the deployment environment. A related ",(0,t.jsx)("a",{href:"https://www.nist.gov/news-events/news/2026/02/new-concept-paper-identity-and-authority-software-agents",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"NIST identity and authorization concept paper"})," focuses on identification, authorization, auditing, and non-repudiation for software agents. Those are the right foundations."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"A service identity can establish that an AI SOC agent is allowed to use a cloud, identity, or endpoint API. It cannot by itself establish that a request to suspend a particular executive’s account, isolate a production host, or suppress a newly created detection is appropriate. Those decisions depend on the target, the arguments, the initiating user, the incident state, and the surrounding evidence. Authority must travel with the tool call, then be evaluated at the moment of execution."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What needs a policy boundary"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"An AI SOC needs broader permissions to investigate than to contain or modify an environment. The policy should distinguish those paths explicitly."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Read and enrichment operations."})," Limit searches to approved tenants, indices, time ranges, and data classifications. Redact secrets and personal data before they reach an external model or an unapproved destination."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Endpoint and identity response."})," Require explicit authority for actions such as host isolation, user suspension, password reset, token revocation, and group-membership changes. Escalate high-impact targets for human approval."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Cloud and infrastru
1cture changes."})," Constrain destructive API calls by account, region, resource tag, and change window. An investigation agent should not inherit unrestricted production administration."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Detection and case management."})," Preserve provenance for rule changes, alert closure, ticket updates, and automated verdicts so an analyst can reconstruct what evidence drove the action."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Remote tools and MCP servers."})," Allow only registered tools with scoped credentials and known data destinations. Tool descriptions and results are inputs to the agent, so they belong in the threat model as well."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The goal is to keep the speed of an AI SOC while making high-impact actions governable. Start with the evidence path, then put controls where the agent crosses into a tool or system of record."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Inventory every tool call."})," Map each agent capability to its data source, credential, destination, argument set, and possible side effect. Include ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"})," connections alongside direct APIs."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Separate investigation from response."})," Give agents broad read access only where it is justified. Use narrower, time-bound authority for containment and require approval for irreversible or high-blast-radius actions."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Evaluate arguments at runtime."})," A policy should inspect the exact command, API method, destination, target resource, and user context before execution. Static role assignment cannot provide that decision by itself."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Keep an action-level audit trail."})," Record the agent, initiating user, policy version, tool, arguments, decision, and evidence reference for every sensitive operation. Map detections and tests to ",(0,t.jsx)("a",{href:"https://atlas.mitre.org/",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"MITRE ATLAS"})," where it improves coverage and red-team exercises."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Begin in observe mode."})," Measure the actions an agent would take, tune policies against real cases, then enforce the boundaries that are understood and high confidence."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The mature AI SOC will pair capable reasoning with constrained execution. Analysts should receive faster investigations and stronger context. The environment should receive a precise, policy-backed decision before an agent changes it. That is the boundary that lets autonomy improve security operations without quietly expanding operational risk."})]})},{id:"google-dialogflow-cx-rogue-agent-shared-runtime",title:"Google Dialogflow CX Rogue Agent Showed How One Playbook Editor Could Reach Every Code Block Agent",description:"On July 7, 2026, Rogue Agent showed how one Dialogflow CX playbook edit permission could hijack every Code Block agent in a project.",date:"July 8, 2026",category:"Agent Security",ogImage:"https://d205xtizsu1yjh.cloudfront.net/blog/google-dialogflow-rogue-agent-2026-07-08.png",ogImageAlt:"Diagram showing how a Rogue Agent Dialogflow CX compromise could spread across multiple agents through a shared Cloud Run runtime.",keywords:["Rogue Agent Dialogflow","Dialogflow CX vulnerability","Google Dialogflow CX security","dialogflow.playbooks.update permission","Dialogflow Code Blocks","shared Cloud Run runtime","code_execution_env.py overwrite","AI chatbot phishing risk","VPC Service Controls bypass","Google IMDS exposure","enterprise chatbot security","agent runtime isolation","Prismor execution boundary","Google Cloud AI security"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On July 7, 2026, ",(0,t.jsx)("a",{href:"https://thehackernews.com/2026/07/rogue-agent-flaw-could-have-let.html",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"The Hacker News covered Varonis’ Rogue Agent finding"})," in ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Dialogflow CX"}),": a single account with ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"dialogflow.playbooks.update"})," on one agent could have poisoned the shared runtime used by every ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Code Blocks"}),"-enabled agent in the same Google Cloud project. That turns what looks like a narrow content-edit permission into cross-agent code execution."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The impact was serious because the compromised runtime sat inside Google’s managed environment, outside the customer’s visibility, with access to live conversation history and the bot response path. According to ",(0,t.jsx)("a",{href:"https://www.varonis.com/blog/rogue-agent-dialogflow-attack",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Varonis’ technical write-up"}),", an attacker could have quietly exfiltrated chats, pushed attacker-written prompts back to users, and used the bot itself as a phishing surface. Google said the issue was fixed in June 2026 and that there is no evidence of in-the-wild abuse."]}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9i8xIVWZcplpj-QuKnJKGAJjGi0Xq-q2R_luyy-HYXWkpsAPTYASmVbm2w2DoNOQkA81fyu0OQsbflhLykcYQpv66UDBeRxU1v5-xq7kQDQMS0cmvsCFmZI36jfyGxh6xrroU4hNhH_8_nOyXV_WG07om2t4riI-HP4wzE3HJr2KJ3-sUnKxbTNhV84k/s1700-e365/google-chatbots.jpg",alt:"Google chatbot illustration from the original Rogue Agent coverage",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Rogue Agent was a shared-runtime problem: compromise one editable agent, then inherit reach into every other agent using the same Code Block environment."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Rogue Agent worked"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Dialogflow CX"})," lets teams attach custom Python to Playbooks through ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Code Blocks"}),". That code runs inside a Google-managed ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Cloud Run"})," environment. Varonis found that agents using Code Blocks inside the same project shared that environment, including a writable file named ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"code_execution_env.py"}),", which was responsible for wrapping developer code and passing it to Python’s ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"exec()"}),"."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Once an attacker could edit one agent’s playbook, they could use a Code Block to overwrite that shared file with a modified version fetched from an external server. From that point forward, every subsequent Code Block execution across the project would run inside attacker-controlled wrapper logic. That wrapper could read conversation history, inspect session state, and call the built-in response helper to make the bot say whatever the attacker wanted."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["Varonis al
1so reported two related boundary failures. The runtime had unrestricted outbound internet access, which made direct exfiltration and command retrieval possible over standard libraries such as ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"urllib"}),". It also exposed the instance metadata service, or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"IMDS"}),", returning a low-privilege Google-managed token. Even though that token was limited, the larger lesson is plain: a sandbox that can rewrite its own execution wrapper, reach the open internet, and query metadata is not meaningfully isolated."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What was affected"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The issue was narrower than all of Dialogflow, but broader than one chatbot."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Dialogflow CX"})," agents using ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Playbooks"})," and ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Code Blocks"}),"."]})," Agents without custom Python were outside this path."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:["Projects where a principal held ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"dialogflow.playbooks.update"}),"."]})," The exploit started from an insider, a compromised developer account, or another identity that already had that permission."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:["Organizations relying on ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"VPC Service Controls"})," for egress assumptions."]})," Varonis said the runtime sat outside that perimeter and could still reach the public internet."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Teams handling sensitive chat data."})," Customer support, healthcare, finance, and internal assistant workflows were the obvious high-risk deployments because the bot could read and replay exactly what users typed."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why this incident stands out"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Many AI incidents start with prompt injection or model manipulation. Rogue Agent did not need either. The attack path lived in ordinary product features, ordinary IAM, and a shared execution layer customers could not inspect. That makes it a cleaner example of the real operational problem in agent systems: permissions that sound administrative or editorial often collapse directly into runtime power."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"It also shows why provider-managed agent runtimes deserve the same scrutiny teams already apply to CI runners, serverless functions, and browser sandboxes. If multiple agents share code paths, file system state, or egress paths behind the scenes, then one mis-scoped permission can become a project-wide compromise. The bug was fixed. The design lesson remains."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["If you used ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Dialogflow CX"})," Code Blocks before Google’s June 2026 fix, treat this like a runtime compromise question, not a simple c
1onfiguration review."]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:["Audit every holder of ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"dialogflow.playbooks.update"}),"."]})," In this case, edit access was execution access."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Review historical playbook changes and log anomalies."})," Start with Dialogflow API ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"DATA_WRITE"})," events, unusual source IPs, odd access times, and failed requests that may expose Code Block exceptions."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Reduce egress assumptions for managed AI runtimes."})," If a provider-controlled execution path can reach the public internet, treat that path as an exfiltration channel until proven otherwise."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Put a policy boundary in front of downstream actions."})," If the agent’s code execution and outbound actions were routed through Prismor, the exploit chain would have broken at the first policy violation: fetching a replacement payload from an untrusted domain, sending conversation data to an external sink, or invoking tools outside the session’s approved scope."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Ask vendors direct isolation questions."})," Shared wrappers, writable system files, metadata reachability, and hidden egress paths are architecture questions, not edge cases."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Prismor matters here because Rogue Agent was an action problem, not only a permission problem. The attacker needed the compromised runtime to do real things next: pull remote code, move data to an attacker-controlled destination, and execute behavior that was outside the bot’s intended job. A runtime guard at the tool-call boundary is where those steps become governable."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"https://d205xtizsu1yjh.cloudfront.net/blog/google-dialogflow-prismor-2026-07-08.png",alt:"Diagram showing Prismor intercepting Dialogflow agent actions and blocking malicious code from reaching a Google-managed Cloud Run runtime",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"With an execution boundary in front of agent actions, the malicious payload fetch and exfiltration path become blockable events instead of post-incident evidence."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Prismor would have helped by intercepting the malicious follow-on steps shown in the diagram above: the payload fetch, the attempt to route conversation data outward, and any tool use that fell outside approved policy. That is the practical lesson from this incident: identity controls decide who may edit an agent, but execution controls decide whether a compromised agent can still reach sensitive tools, unapproved destinations, and live data flows. Teams that put both layers in place are much harder to turn into full-project incidents."})]})},{id:"ai-agent-security-2026-tool-call-boundary",title:"AI Agent Security in 2026: Why the Control Plane Has to Sit at the Tool-Call Boundary",description:"On May 18, 2026, NIST said AI agent security concerns are slowing adoption. The missing control plane sits where tool calls turn into actions.",date:"July 7, 2026",category:"Agent Security",ogImage:"/blog/ai-agent-security-tool-call-boundary-2026-07-07.png",ogImageAlt:"Hand-drawn diagram showing an AI agent on the left, Prismor at the tool-call boundary in the center, and Shell, Files, API, and MCP tools on the right.",keywords:["AI agent security","agentic AI security","secure AI agents","AI agent governance","AI agent runtime security","agent execution control plane","tool-call boundary security","MCP server security","agentic AI attack surface","OWASP Top 10 for Agentic Applications","NIST AI agent security","OpenAI Agents SDK security","LangChain agent security","CrewAI 
1security","Prismor AI agent security"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On May 18, 2026, ",(0,t.jsx)("a",{href:"https://www.nist.gov/publications/summary-analysis-responses-request-information-regarding-security-considerations-ai",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"NIST published its summary analysis of responses on AI agent security"})," and landed on the point many teams are already feeling in production: security concerns are now a barrier to adoption. That matters because the question is no longer whether agents will reach real systems. They already do."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The category is hardening fast. ",(0,t.jsx)("a",{href:"https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"OWASP published its Top 10 for Agentic Applications"})," in December 2025. By May 6, 2026, ",(0,t.jsx)("a",{href:"https://censys.com/blog/mcp-servers-on-the-internet/",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Censys said it had observed more than 21,000 internet-facing servers"})," speaking ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"}),". Anthropic’s own documentation now tells users to ",(0,t.jsx)("a",{href:"https://docs.anthropic.com/en/docs/agents-and-tools/remote-mcp-servers",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"connect only to remote servers they trust"}),". Put those together and the pattern is clear: AI agent security is becoming a real category, and the center of gravity is shifting from model safety alone to execution control."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why this category is getting real"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Standards work is usually a lagging indicator. By the time NIST asks for input on a problem, the problem is already operational. In its ",(0,t.jsx)("a",{href:"https://www.nist.gov/news-events/news/2026/01/caisi-issues-request-information-about-securing-ai-agent-systems",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"January 12, 2026 request for information"}),", NIST called out the distinct risk created when model outputs are connected directly to software functionality, including indirect prompt injection, poisoned models, and harmful actions taken without adversarial input. That is a strong signal that AI agent security has moved past theory and into deployment engineering."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The second signal is how the risk is being categorized. OWASP’s 2025 list for LLM and GenAI applications includes prompt injection, sensitive information disclosure, supply chain, improper output handling, and excessive agency. The 2026 agentic list narrows that further around the way autonomous systems plan, delegate, call tools, and abuse privileges. The model still matters. The part that hurts you in production is the path from model output to action."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Our read on the market is that three clusters are forming at once: discovery and posture tools that tell you where agents exist, identity layers that decide what credentials they should get, and execution-layer controls that decide whether a specific action should run right now. That last layer is where the blast radius lands. It is also the layer most teams still do not have."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What is affected"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This is broader than one framework or one protocol. Any system that lets a model call tools inherits the same control problem, even if the surrounding stack looks very different."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Coding agents in IDEs."})," Agents that can run shell commands, edit files, install packages, and reach local credentials."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Framework agents."})," Teams building on ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"OpenAI Agents SDK"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"LangChain"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"LangGraph"}),", or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"CrewAI"})," where a model can invoke external tools as part of a workflow."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"}),"-connected systems."]})," Remote servers exposing filesystems, databases, internal APIs, deployment hooks, and security tooling."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Customer-facing and internal business agents."})," Systems that can read tenant data, trigger workflows, approve actions, or touch regulated records."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Where legacy controls keep missing the problem"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Most existing security controls were built for a human-paced operator. They inspect code before deployment, look at network edges, or review logs after the fact. Agents collapse those stages. The same session can read an untrusted document, treat a hostile instruction as relevant context, reach for a high-privilege tool, and execute the tool call before anybody notices the chain forming."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["That is 
1why prompt injection becomes more dangerous in an agentic system than in a standalone chatbot. In a chat window, a bad prompt can generate a bad answer. In an agent workflow, the same prompt can lead to a database query, a file write, a package install, a cloud action, or a credentialed API call. ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"LLM01"})," and excessive agency become the same operational problem once the agent is live: they converge at the tool call."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The same shape shows up again in remote tool infrastructure. ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"})," is useful because it turns tools and data sources into a common interface for agents. It also concentrates trust. If the server is weakly authenticated, over-privileged, or allowed to hand the agent unsafe tool descriptions and results, the agent inherits that weakness immediately."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This is the practical insight behind the recent standards work: monitoring prompts is useful, auditing outcomes is useful, and identity is necessary. None of them answer the last decision. Should this exact action execute, with these arguments, for this user, in this session, against this tool, right now?"}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor solves the execution gap"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Prismor is built around that last decision. It sits between the agent’s reasoning layer and the tool it is about to execute, intercepting tool calls before they run. Instead of waiting for a shell command, file write, package install, or API call to show up in a log, Prismor evaluates the action in real time and can allow it, observe it, or block it."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The control point is intentionally thin. For framework agents, Prismor wraps the execution layer used by ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"OpenAI Agents SDK"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"LangChain"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"LangGraph"}),", and ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"CrewAI"}),". For coding agents and ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"}),"-native workflows, it watches the same boundary where tools are invoked. Existing agent logic does not need to be rewritten to get a control plane."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That gives teams a few things they usually do not have today: per-user and per-team policy, an audit trail of what the agent tried to do, policy-as-code, and a clean path from observe mode to enforce mode. It also creates a place to express security intent in operational terms. A support agent should not write to production infrastructure. A coding agent should not exfiltrate secrets. A document agent should not call an untrusted remote tool just because a prompt told it to."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The broader point is that AI agent security needs both identity and behavior control. Credentials answer who the agent is allowed to be. Prismor answers whether the agent should be allowed to do this exact thing next. That is the missing layer in many current deployments."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If you are putt
1ing agents into production, the shortest useful plan is to make the execution layer visible and governable before you scale adoption."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Inventory every tool surface."})," Include local shell access, file writes, package managers, internal APIs, and every ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"})," server an agent can reach."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Separate identity from action control."})," Short-lived credentials and scoped access matter. They do not replace a runtime decision point on tool use."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Start with observe mode."})," Watch what agents do in production sessions before you lock policies down. Then move high-confidence rules to enforcement."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Thread user context through every action."})," The same agent should not behave identically for every employee, customer, or workflow."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Treat remote tool infrastructure as part of the attack surface."})," Trust boundaries do not end at the model or at your app server. They extend to every tool description, tool result, and remote action path the agent can consume."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The critical shift is to stop framing agent security as a model-only problem. The industry is already telling us where this goes next: more standards, more identity, more remote tools, and more autonomous actions. Teams that prepare well will be the ones with a control plane at the action layer, where an agent’s next step can still be understood, scoped, and stopped before it becomes an incident."})]})},{id:"exposed-mcp-servers-agent-tool-call-security",title:"Every Agent Has a Door. Most Are Unlocked.",description:"By May 2026, Censys counted over 21,000 exposed MCP servers. CVE-2026-33032 and Anthropic’s own Git MCP flaws show exactly what an unlocked one costs.",date:"July 3, 2026",category:"Agent Security",keywords:["MCP server security","exposed MCP servers","unauthenticated MCP servers","Model Context Protocol security","AI agent tool-call security","agentic AI attack surface","agent security runtime","prismor open source","tool-call boundary security","MCP authentication","CVE-2026-33032","MCPwn nginx-ui vulnerability","Censys MCP scan","Anthropic Git MCP server RCE","MCP OAuth 2.1 optional authentication"],ogImage:"https://d205xtizsu1yjh.cloudfront.net/blog/mcp-tool-call-boundary-diagram-2026-07-03.png",ogImageAlt:"Every Agent Has a Door. Most Are Unlocked. Diagram showing Prismor between an IDE agent and MCP servers with no auth, weak auth, and authenticated states.",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"People think the risk in AI agents lives in the model. Get the prompt right, filter the output, and you are safe. That is the story most teams tell themselves."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["By late April 2026, Censys had already counted 12,520 internet-facing"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"MCP"})," ","servers across 8,758 IP addresses in 56 countries. Two weeks later the count passed 21,000. Model Context Protocol is the wire an agent uses to reach a tool: a database, a filesystem, a deploy pipeline, a company’s internal API. Censys could count every one of those servers for a specific reason: MCP defines an OAuth 2.1 authorization scheme, then marks it optional. A server that skips it is not misconfigured. It is following the spec."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The wire behind the room"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Here is the part people miss: a model is a room where decisions get made. The decisions do not matter until they turn into actions, and actions travel through tool calls. That is 
1where the agent writes a file, runs a command, hits an API, or talks to an MCP server. Secure the room all you want. If the wires leaving it are unlocked, the room was never the risk."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"An open MCP server is a door with no lock and no camera. Anyone who finds it can hand the agent a tool description, a fake instruction, a poisoned result, and the agent has no way to tell that from the real thing. It does not know the difference between the team that built it and a stranger who found the door. It sees a tool call, and it executes."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Same gap, new wire"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This is the same failure mode, dressed up in new language each time. Supply chain attacks work because a package’s install script is a door nobody watched. Prompt injection works because the model cannot tell instructions from data once they are both text. MCP exposure is the same gap wearing a new protocol. Same shape, same blind spot, different wire."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A year earlier, in July 2025, researchers at Knostic went looking for these doors the same way Censys later would. They found 1,862 servers and manually checked 119 of them. All 119 handed over their internal tool listings to anyone who asked, no credentials required. Nothing about that finding was subtle, and nothing about it got fixed. It got bigger instead."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The doors keep failing in the same specific way. In nginx-ui, the endpoint an agent uses to manage a server, ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"/mcp"}),", checked for a valid session. Its sibling endpoint, ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"/mcp_message"}),", checked an IP whitelist that shipped empty, which the code read as allow all. One missing line, ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"middleware.AuthRequired()"}),", and any attacker on the network could restart nginx, rewrite its configuration, and reload it into whatever shape they wanted. Cataloged as CVE-2026-33032, CVSS 9.8, it was already being exploited in the wild by mid-April 2026."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Even Anthropic’s own reference implementation carried the same shape of problem. Its Git MCP server let an agent read a malicious README or a poisoned issue description, use a path-traversal bug to reach a directory it should never have touched, initialize a git repository there, plant a config file with a shell hook inside it, then trigger that hook through a second, unrelated bug. Three flaws, chained, into full code execution, and the attacker never needed direct access to the machine. The company that wrote the protocol shipped the same blind spot it was warning everyone else about."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That difference matters because most security tools were built to watch the room, not the wire. A scanner can tell you a package looks suspicious after it is already installed. A log can tell you a command ran after it already ran. None of that sits at the place where a decision turns into an action, which means none of it catches the moment that matters."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Watching the boundary, not the aftermath"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["That is the boundary we built"," ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor"})})," ","to sit on. It is open source, it runs on the developer’s own machine, and it watches the tool-call boundary directly: every shell command, every file write, every package install, every MCP interaction, checked before it executes, not after. If an agent reaches for an unauthenticated MCP server, or a tool call that does not match what the session was supposed to be doing, Prismor is positioned to catch it at the door, not in the postmortem. A single"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"pip install prismor"}
1)," ","is enough to start watching that boundary on one machine."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Most teams have never gone looking for their own doors. Before trusting another MCP integration, it is worth checking what is already open:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Inventory every MCP server in use."})," Internal and third-party. If nobody can list them, nobody is watching them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Require authentication on every server, no exceptions."})," A convenience deployment today is an open door tomorrow."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Treat tool descriptions and tool results as untrusted input."})," An MCP server can describe its own tools in whatever way benefits an attacker, and a file the agent reads can carry instructions of its own. The agent should not take either on faith."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Do not assume a vendor-shipped default is safe."})," Anthropic’s own reference Git MCP server needed three CVEs and the eventual removal of a tool before it was."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Put a control at the tool-call boundary, not just around the model."})," Watching prompts and outputs will always miss the moment the agent acts."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"An agent is only as safe as its least-locked door, and most teams have never gone looking for the doors. Once you see it that way, AI safety stops being a model problem. It becomes a wiring problem, and wiring problems get fixed by looking at the wires, not by talking to the room."})]})},{id:"why-we-built-prismor-agent-security-runtime",title:"Why We Built Prismor to Secure AI Coding Agents at the Tool-Call Boundary",description:"Prismor grew out of a simple problem: AI coding agents can act at machine speed, and most security tools only inspect the damage afterward.",date:"June 26, 2026",category:"Agent Security",keywords:["Prismor agent security","immunity-agent","Agentic Controls","tool-call boundary security","AI coding agent runtime security","secure Claude Code","secure Cursor agents","MCP server security","prompt injection runtime defense","signed policy for AI agents","redacted telemetry agent security","local-first agent security","agent tool-call monitoring","prismor setup","agent security control plane","secret cloaking AI agents"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"AI coding agents now write files, install packages, fetch remote resources, and run shell commands on their own. We kept watching teams adopt them faster than their security controls could keep up, and the gap kept showing up in the same place: the moment an agent turns a plan into an action."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["That is why we built Prismor. The open source runtime ships as"," ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor"})}),", lives on the developer’s machine, and watches the tool-call boundary in real time. When an agent tries to run a destructive command, install a poisoned package, expose a secret, or follow a hostile MCP instruction, Prismor can stop the action before it lands."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why we built it"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"We tried scanner-shaped approaches first. They were useful, then they ran out of road. A scanner can tell you that a package is risky, that an MCP server looks strange, or that a config file holds a 
1secret. Those are real findings. They still arrive before or after the moment that matters."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Agents move inside the session. They decide, they call tools, and they chain one action into the next without waiting for a human checkpoint. By the time a traditional control notices that"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"rm -rf"})," ","ran, that a publish token left the machine, or that a poisoned install script executed, the agent already got what it wanted. We wanted a control that sits where the decision becomes execution."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That boundary turned out to be the right one. It is specific enough to catch real damage, early enough to stop it, and close enough to the developer that we could keep the whole system local-first. That last part mattered. Security teams need evidence. Developers need to know their code and secrets stay off somebody else’s cloud."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor works"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Prismor installs lightweight hooks into the agent workflow and evaluates every tool call before it executes. Shell commands, file writes, package installs, MCP interactions, network egress, and secret handling all pass through the same decision point. The runtime can observe, warn, or block based on policy."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On a single machine, that means you can install"," ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor"})})," ","and get useful protection immediately. For teams,"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor-web"})," ","adds the control plane around it: device enrollment, signed policy distribution, redacted telemetry, exemptions, and org-wide visibility into what agents are doing across managed repositories."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The design constraint from the start was trust. Policies are signed. The runtime verifies them before applying them. Local protection keeps working if the control plane is unavailable. Telemetry can be redacted at the source. A fresh install stays useful even if you never enroll a device. Those choices make the system easier to adopt because they respect the environment it is trying to protect."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"We also wanted one runtime to cover the whole surface instead of another pile of point products for prompt injection, secret cloaking, supply-chain checks, MCP vetting, and audit trails. The agent sees one workflow. Security should too."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What it protects"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Prismor was built for the failures we kept seeing in real agent workflows, the quiet ones that start as convenience and turn into blast radius."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Destructive tool use."})," Commands that wipe files, rewrite permissions, force pushes, or alter system state can be stopped before execution."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Secret exposure."})," Prismor can cloak sensitive values before they reach the model, the shell, or logs that hang around longer than anyone expects."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Supply-chain abuse."}
1)," Package installs, postinstall hooks, and suspicious dependency behavior can be inspected while the agent is still trying to pull them in."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MCP and prompt injection risk."})," Untrusted tool descriptions, hostile server instructions, and poisoned resources can be caught at the point where the agent tries to act on them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Policy drift across a team."})," Signed policy, scoped exemptions, and enrolled devices give security teams a way to standardize what safe agent behavior looks like without turning every laptop into a support ticket."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If your team is already building with AI coding agents, the right move is to put a control at the action layer now. Start small and make it real:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Install the runtime locally."})," Start with"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"pip install prismor"})," ","and run"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prismor setup"})," ","to hook it into the agents your team already uses."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Begin in observe mode."})," Watch what your agents do before you tighten policy. Most teams learn something useful in the first session."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Turn on enforcement for the obvious high-risk actions."})," Destructive shell patterns, secret exfiltration paths, unsafe installs, and untrusted remote execution paths should not wait for a postmortem."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Enroll devices when the team grows."})," Use the control plane for signed policy rollout, redacted telemetry, and device-level visibility once agent usage spreads past a couple of laptops."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Treat MCP and agent tooling like supply chain."})," Review what gets installed, what gets permission to execute, and what the agent is allowed to trust by default."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The larger shift here is simple: AI coding agents changed where security has to sit. The useful control point is no longer the code after it lands or the endpoint after the action fires. It is the moment an agent reaches for a tool. Teams that secure that moment will ship faster with fewer surprises. Teams that skip it will keep learning about agent risk from the cleanup."})]})},{id:"easy-day-js-mastra-npm-supply-chain-attack",title:"143 Mastra npm Packages Backdoored via easy-day-js Dependency Swap",description:"On June 17, 2026, an attacker used a former contributor's stale npm access to push malicious versions of 143 @mastra packages. The payload, hidden inside a typosquatted dayjs clone, installed a cross-platform RAT with OS-level persistence on macOS, Linux, and Windows.",date:"June 17, 2026",category:"Supply Chain Security",keywords:["easy-day-js npm malware","mastra npm supply chain attack","easy-day-js typosquat dayjs","mastra packages compromised June 2026","@mastra npm backdoor","npm postinstall hook RAT","npm contributor account takeover","cross-platform nodejs rat npm","crypto wallet extension stealer npm","npm dependency injection attack","sergey2016 npm malicious package","JFrog easy-day-js analysis","npm supply chain attack 2026","mastra ai framework security","stale npm access token attack"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On June 16, 2026, at 07:05 UTC, an npm account named"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"sergey2016"})," ","published"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"}),". The package was clean. It was a fully functional copy of the legitimate"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"dayjs"})," ","date library, mirroring its author name, version numbering, homepage, repository URL, and license word for word. Its only purpose was to sit there long enough to look credible."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["Eighteen hours later, at 01:01 UTC on June 17,"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"})," ","appeared. Twenty-six minutes after that, the"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ehindero"})," ","npm account began republishing 143 packages across the"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@mastra"}
1)," ","namespace with the malicious dependency baked in. The campaign ran for 88 minutes."," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ehindero"})," ","was a legitimate former Mastra contributor. Their scope access had never been revoked."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the attack worked"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Installation triggered a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"postinstall"})," ","hook that executed an obfuscated script called"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"setup.cjs"}),". The first stage disabled TLS certificate verification, wrote local marker files, downloaded a second-stage payload from an attacker-controlled server, launched it as a detached process, then deleted itself. The install appeared to complete normally."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The second stage was a cross-platform Node.js remote access trojan."," ",(0,t.jsx)("a",{href:"https://research.jfrog.com/post/easy-day-js/",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"JFrog Security Research"}),", who discovered and analyzed the campaign, found it collected system reconnaissance on arrival: username, hostname, OS and architecture, running processes, and installed applications. It then harvested browser history hostnames from Chrome, Brave, and Edge, and inventoried which of 166 known cryptocurrency wallet browser extensions were installed. That last step signals the campaign’s likely priority target: developers holding crypto wallet access or high-value AI infrastructure credentials."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Persistence was written before any data left the machine. On macOS, the RAT registered a LaunchAgent at"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/Library/LaunchAgents/com.nvm.protocal.plist"}),". On Linux, it created a systemd user service at"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/.config/systemd/user/nvmconf.service"}),". On Windows, it wrote a Registry Run key named"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"NvmProtocal"}),". All three survive a reboot. C2 traffic was directed to"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"23.254.164.92"})," ","and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"23.254.164.123"}),"."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Beyond the initial collection, the RAT opened a remote module execution channel. The attacker could push arbitrary Node.js or shell commands to any compromised machine and receive output back. The recon was the first move. The channel was the foothold."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What was affected"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Mastra is a JavaScript and TypeScript framework for building AI applications."," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@mastra/core"})," ","alone had more than 918,000 weekly downloads at the time of the attack. The broader namespace was pulling an estimated 8 million installs per week across roughly 29 million monthly downloads. Mastra environments routinely hold LLM API keys, cloud provider credentials, CI/CD tokens, and database connection strings."]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"[email protected]:"}
1)," the malicious dependency, published June 17, 2026 at 01:01 UTC. Version"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.11.21"})," ","was clean."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"143 @mastra packages:"})," republished with the bad dependency starting 01:27 UTC on June 17, including"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@mastra/core"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@mastra/ai-sdk"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@mastra/auth"}),","," ","and the full"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@mastra/voice-*"})," ","family."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Safe versions:"})," @mastra packages predating the June 17 publish window do not contain"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"easy-day-js"}),". npm pulled malicious versions and reverted latest tags after the campaign was identified."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What makes this attack different"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Publishing a clean version first is a deliberate technique. A package with a publication timestamp and an existing version history does not trigger newness-based detection. By the time"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.11.22"})," ","appeared, easy-day-js already looked like an established minor-version library. Socket flagged it within six minutes anyway. JFrog Curation customers using an immaturity policy were protected within 24 hours. Both catches came from behavioral signals rather than from recognizing the package as new."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The ehindero account is the other thread worth pulling. The attacker did not compromise Mastra’s codebase. They used a real account with real publish rights that had gone stale. Access reviews feel administrative until a former contributor’s credentials become the entry point for an 88-minute mass compromise. Revoking scope access when someone leaves a project is a blast radius decision made in advance, not a hygiene task."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Any npm install that resolved"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"})," ","as a transitive dependency should be treated as a full compromise. Start here:"]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check lock files for easy-day-js."})," Search"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"package-lock.json"})," ","or"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"yarn.lock"})," ","for the string"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"easy-day-js"}),". Its presence confirms the malicious dependency was resolved at install time."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Scan for persistence artifacts."})," On macOS, look for"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/Library/LaunchAgents/com.nvm.protocal.plist"}),". On Linux, check"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/.config/systemd/user/nvmconf.service"}),". On Windows, inspect the Registry Run key"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"NvmProtocal"}),"."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate all credentials that were accessible during the session."})," LLM API keys, cloud tokens, npm publish tokens, CI/CD secrets, and cryptocurrency wallet credentials should all be cycled, in that order."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Review network logs for C2 contact."})," Filter outbound traffic for"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"23.254.164.92"})," ","and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"23.254.164.123"}),". Either address appearing in logs confirms the second stage connected."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Reinstall from clean versions."})," Remove"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"easy-day-js"})," ","from dependency manifests and lock files, pin @mastra packages to versions predating June 17, and run a fresh install."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The pattern worth remembering is broader than typosquatting: a dependency that published yesterday, from a single account, with a postinstall script, is worth pausing on regardless of how familiar its metadata looks. Teams that flag transitive dependencies by publication age and account history catch this category of attack before the install runs. The postinstall hook is a legitimate feature that gets misused at a steady clip, and npm has signaled plans to restrict it in v12. Until that ships, the hook remains the fastest route from a malicious package to a compromised machine."})]})},{id:"trapdoor-crypto-stealer-npm-pypi-crates",title:"TrapDoor: 34 Malicious Packages Stole Crypto Wallet Keys and SSH Credentials Across npm, PyPI, and Crates.io",description:"TrapDoor planted 34 malicious packages across npm, PyPI, and Crates.io in May 2026, stealing cryptocurrency wallet keystores, SSH keys, and cloud tokens from blockchain and AI developers.",date:"May 25, 2026",category:"Supply Chain Security",keywords:["TrapDoor malware npm","malicious npm packages crypto 2026","PyPI supply chain attack May 2026","crates.io malicious packages rust","build.rs supply chain attack","postinstall hook credential theft npm","crypto wallet keystore theft","Sui Solana wallet stealer npm","blockchain developer credential theft","multi-registry supply chain attack 2026","trap-core.js npm malware","eth-security-auditor pypi malware","mnemonic-safety-check npm malware","supply chain attack AI developers 2026","npm pypi rust supply chain security"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Beginning May 22, 2026, a set of 34 malicious packages began appearing across npm, PyPI, and Crates.io with a shared goal: reach developer machines in the cryptocurrency, DeFi, and AI ecosystems, collect credentials, and send them out quietly."," ",(0,t.jsx)("a",{href:"https://socket.dev/blog/trapdoor-crypto-stealer-npm-pypi-crates",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"Socket researchers, who named the campaign TrapDoor"}),", caught the first package at 20:20:18 UTC on May 22. By the time the wave finished, more than 384 versions and artifacts had been published across all three registries. Average time from publication to detection was five minutes and 56 seconds. The fastest catch w
1as 58 seconds."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The package names gave the campaign its cover. Names like"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"mnemonic-safety-check"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"solidity-deploy-guard"}),", and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"eth-security-auditor"})," ","read exactly like utilities a blockchain or AI developer would pull without a second thought. Developers in these spaces routinely install small helper packages; the attacker built around that behavior."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the attack works"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Each registry got a different execution trigger, which made the campaign harder to catch with any single scanning approach. On npm, 21 packages fired a postinstall hook at install time. The hook loaded a shared payload called"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"trap-core.js"}),": 1,149 lines, 48,485 bytes. Before exfiltrating anything, the payload made live calls to AWS and GitHub API endpoints to test each stolen credential. Only the ones that responded as valid were packaged for transmission. Encryption used Fernet symmetric encryption layered with ECDH key exchange."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The seven PyPI packages used a simpler path: code ran on module import. A plain"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"import"})," ","statement was enough to trigger a download from an attacker-controlled GitHub Pages domain. The downloaded file ran locally via"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"node -e"}),". In practice, the Python packages acted as launchers for the same JavaScript infrastru
1cture used on npm."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On Crates.io, the six packages used"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"build.rs"})," ","scripts. In Rust projects,"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"build.rs"})," ","compiles and runs before the rest of your project builds. The malicious scripts scanned for local cryptocurrency keystores, XOR-encrypted them with the hardcoded key"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"cargo-build-helper-2026"}),", and pushed the encrypted output to GitHub Gists."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["Beyond the initial theft, TrapDoor wrote for persistence. A recovered GitHub token with repository access triggered a second stage: the malware dropped"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:".cursorrules"})," ","and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"CLAUDE.md"})," ","files to redirect AI coding assistants, installed git and shell hooks, created systemd services and cron jobs, and attempted to move laterally using stolen SSH keys. Separately, the attacker submitted pull requests to LangChain, Langflow, LLaMA Index, MetaGPT, OpenHands, and browser-use, each injecting a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:".cursorrules"})," ","file carrying hidden Unicode characters and links to attacker-controlled infrastructure."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What was affected"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"All 34 packages across the three registries were reported to the respective registries after detection. The full list:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"npm (21 packages):"})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"async-pipeline-builder"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"build-scripts-utils"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"chain-key-validator"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"crypto-credential-scanner"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"defi-env-auditor"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"defi-threat-scanner"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"deployment-key-auditor"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"dev-env-bootstrapper"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"eth-wallet-sentinel"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"llm-context-compressor"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"mnemonic-safety-check"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"model-switch-router"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"node-setup-helpers"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"project-init-tools"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"prompt-engineering-toolkit"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"solidity-deploy-guard"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"token-usage-tracker"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"wallet-backup-verifier"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"wallet-security-checker"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"web3-secrets-detector"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"workspace-config-loader"})]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"PyPI (7 packages):"})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"cryptowallet-safety"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"data-pipeline-check"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"defi-risk-scanner"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"env-loader-cli"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"eth-security-auditor"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"git-config-sync"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"solidity-build-guard"})]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Crates.io (6 packages):"})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"move-analyzer-build"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"move-compiler-tools"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"move-project-builder"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"sui-framework-helpers"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"sui-move-build-helper"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"sui-sdk-build-utils"})]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why this campaign stands out"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Running a coordinated campaign across three registries at once is rare. Most supply chain attacks settle on one ec
1osystem. TrapDoor adapted its execution method to each: a postinstall hook for Node.js, an import side effect for Python, a build script for Rust. The PyPI packages routed through the same JavaScript payload infrastructure used on npm, suggesting the attacker built a single backend and wrote registry-specific launchers on top of it."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The attacker also published a GitHub repository describing the entire operation as a “Universal AI Agent Extraction Framework,” complete with sections on data exfiltration, prompt injection, AI-agent abuse, and persistence. The internal campaign marker"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"P-2024-001"})," ","shows up across multiple components. Accounts tied to the campaign are GitHub user"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ddjidd564"}),", npm user"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"asdxzxc"}),", and PyPI users"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"asdmini67"})," ","and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"dae5411"}),"."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Any install run that pulled one of these packages should be treated as a potential compromise. Start with credentials that would have been accessible during that session."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Cross-check your lock files."})," Search installed package names against the full TrapDoor list across npm, PyPI, and Crates.io. Lock files preserve exact install history even if packages have since been removed."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate credentials that were accessible."})," SSH keys, AWS and cloud tokens, GitHub tokens, npm publish tokens, and any cryptocurrency wallet credentials on the affected machine should all be cycled."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Look for persistence footprints."})," Check"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/.gitconfig"})," ","and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:".git/hooks/"})," ","for entries you did not add, review shell startup files for unfamiliar lines, and search your home directory and project roots for unexpected"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:".cursorrules"})," ","or"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"CLAUDE.md"})," ","files."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Inspect AI assistant configs for injected content."})," Hidden Unicode characters in configuration files are a signal. If a config file you did not create is present, treat it as suspect."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Review GitHub Actions workflows and recent activity."})," If a token with repository write access was on the machine, check recent workflow runs, commit history, and any new branches or pull requests for changes you did not make."]})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The gap TrapDoor exploits is structural: most dependency scanning tools are built around a single registry. A team running"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"npm audit"})," ","has no view into what a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"build.rs"})," ","script does when a Rust dependency compiles. A Python project running pip-audit does not inspect postinstall hooks that fire in a Node.js context on the same machine. The attack surface spans whichever registries touch your build environment, and monitoring needs to cover all of them."]})]})},{id:"antv-npm-packages-compromised-supply-chain",title:"AntV npm Packages Compromised via Hijacked Maintainer Account",description:"On May 19, 2026, Socket researchers flagged a malicious publish wave across the AntV visualization ecosystem after the atool maintainer account was hijacked. Echarts-for-react and over a dozen related packages were affected across hundreds of versions.",date:"May 19, 2026",category:"Supply Chain Security",keywords:["antv npm compromised","antv supply chain attack","echarts-for-react malware","atool npm account hijacked","TeamPCP npm attack 2026","antv/g2 malicious version","antv/g6 compromised","npm preinstall hook malware","Bun runtime credential stealer","npm visualization library attack","npm maintainer account hijacked 202
16","socket.dev antv investigation","npm supply chain attack May 2026","developer credential theft npm"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On May 19, 2026, Socket’s Threat Research team flagged a coordinated malicious publish wave across the AntV npm namespace. The attack entered through a single hijacked account:"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"atool"}),", a shared maintainer identity with publish access across the AntV visualization ecosystem. Socket attributes the campaign to TeamPCP, the group behind a string of recent npm compromises."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The AntV libraries are used widely in enterprise dashboards and data-intensive interfaces."," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/g2"})," ","and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/g6"})," ","together see millions of weekly downloads."," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"echarts-for-react"}),", also caught in the publish wave, sits at roughly 1.1 million installs per week. Any install run against a compromised version inside a CI environment or on a developer machine with live cloud credentials is precisely the scenario this attack was designed to exploit."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the attack works"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"When a compromised version is installed, a preinstall hook fires before your build starts. The hook fetches a platform-appropriate Bun runtime from GitHub Releases and immediately executes an approximately 11.7 MB obfuscated JavaScript payload. The obfuscation is heavy enough that static analysis tools do not flag it on sight; the payload only reveals itself at runtime."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The payload profiles the execution environment and begins harvesting. The target list is broad: SSH keys, AWS and GCP credential files, Kubernetes configs, GitHub and npm tokens, HashiCorp Vault tokens, and configuration files from AI tooling. Collected material is encrypted with RSA-OAEP-4096 and AES-256-GCM before it leaves the machine. Exfiltration runs across three redundant channels: the domain"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"filev2.getsession[.]org"})," ","(Session Protocol infrastructure), attacker-controlled repositories reached via GitHub’s GraphQL API using stolen tokens, and the typosquat domain"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"git-tanstack[.]com"}),"."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["If the malware acquires a GitHub token with sufficient permissions, it plants persistence. Hooks are inserted into Claude Code and VS Code configurations, a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"gh-token-monitor"})," ","service is installed, and malicious GitHub Actions workflows serialize repository secrets to"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"api.masscan[.]cloud"}),". The campaign also carries a dead-man’s switch: the npm token used for the malicious publishes is described as “IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner.” Revocation triggers"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"rm -rf ~/"})," ","on the affected machine."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What was affected"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"atool"})," ","account had publish access across a wide slice of the AntV namespace. Socket identified hundreds of unique package versions caught in the wave. Confirmed affected packages include:"]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/g2"}),"."]})," Grammar-of-graphics charting library. Millions of weekly downloads."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/g6"}),"."]})," Graph and network visualization."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/x6"}),"."]})," Node-based diagramming and flowchart tooling."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/l7"}),"."]})," Geospatial and map visualization."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/s2"}),"."]})," Spreadsheet-style data table renderer."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/f2"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/g"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/g2plot"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/graphin"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"antv/data-set"}),"."]})," Additional packages across the AntV rendering and data stack."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"echarts-for-react"}),"."]})," Approximately 1.1 million weekly downloads. Maintained by the same atool account outside the AntV namespace."]}),(0,t.jsxs)("li",{children:[(0,t.jsxs)("strong",{children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"timeago.js"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"size-sensor"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"canvas-nest.js"}),"."]})," Utility packages also published under the atool account."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Compromised version list"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Every entry below was published on May 19, 2026 and is confirmed malicious. Versions predating that date are clean. For"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"echarts-for-react"}),", three separate version bumps were pushed on the same day, so even apparent patch releases (3.0.7) are compromised - the last safe release is 3.0.6."]}),(0,t.jsx)("div",{className:"overflow-x-auto mb-6",children:(0,t.jsxs)("table",{className:"w-full text-sm border-collapse",children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{className:"bg-amber-50 border border-amber-200",children:[(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-gray-900 border-r border-amber-200",children:"Package"}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-red-700 border-r border-amber-200",children:"Compromised versions"}),(0,t.jsx)("th",{className:"text-left px-4 py-2 font-semibold text-green-700",children:"Last safe version"})]})}),(0,t.jsx)("tbody",{children:[{pkg:"@antv/g2",bad:"5.5.8, 5.6.8",safe:"≤ 5.4.8"},{pkg:"@antv/g6",bad:"5.2.1, 5.3.1",safe:"< 5.2.1"},{pkg:"@antv/x6",bad:"3.2.7, 3.3.7",safe:"< 3.2.7"},{pkg:"@antv/g2plot",bad:"2.5.35, 2.6.35",safe:"< 2.5.35"},{pkg:"@antv/s2",bad:"2.8.1, 2.9.1",safe:"< 2.8.1"},{pkg:"@antv/f2",bad:"5.15.0, 5.16.0",safe:"< 5.15.0"},{pkg:"@antv/graphin",bad:"3.1.5, 3.2.5",safe:"< 3.1.5"},{pkg:"@antv/data-set",bad:"0.12.8, 0.13.8",safe:"< 0.12.8"},{pkg:"@antv/g",bad:"6.4.1, 6.5.1",safe:"< 6.4.1"},{pkg:"@antv/l7",bad:"2.26.10, 2.27.10",safe:"< 2.26.10"},{pkg:"@antv/graphlib",bad:"2.1.4, 2.2.4",safe:"< 2.1.4"},{pkg:"echarts-for-react",bad:"3.0.7, 3.1.7, 3.2.7",safe:"≤ 3.0.6"},{pkg:"timeago.js",bad:"4.1.2, 4.2.2",safe:"< 4.1.2"},{pkg:"timeago-react",bad:"3.1.7, 3.2.7",safe:"< 3.1.7"},{pkg:"size-sensor",bad:"1.1.4, 1.2.4",safe:"< 1.1.4"},{pkg:"canvas-nest.js",bad:"2.1.4, 2.2.4",safe:"< 2.1.4"}].map(({pkg:e,bad:a,safe:s},r)=>(0,t.jsxs)("tr",{className:r%2==0?"bg-white border border-amber-100":"bg-amber-50/40 border border-amber-100",children:[(0,t.jsx)("td",{className:"px-4 py-2 text-gray-900 border-r border-amber-100",children:e}),(0,t.jsx)("td",{className:"px-4 py-2 text-red-700 border-r border-amber-100",children:a}),(0,t.jsx)("td",{className:"px-4 py-2 text-green-700",children:s})]},e))})]})}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["This list covers the highest-impact packages. The full wave touched over 300 versions across the AntV namespace, including deeper sub-packages (",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@antv/g-plugin-*"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@antv/l7-*"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@antv/x6-plugin-*"}),", and others). Any version of any AntV-namespaced package published on May 19, 2026 should be treated as suspect until individually verified."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What makes this incident notable"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["A single hijacked maintainer account was enough to expose an entire visualization namespace. The AntV ecosystem spans dozens of packages under the same publisher identity, so compromising"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"atool"})," ","gave the attacker a publish path to all of them simultaneously, regardless of how well any individual package was otherwise maintained."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"echarts-for-react"}
1)," ","is also worth calling out separately. It does not sit in the AntV namespace, which means developers who scoped their audit to AntV packages alone would miss it. The attacker did not need to compromise a separate account to reach that package. Shared maintainer identities create blast radii that namespace filtering cannot contain."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Start with your lock files and any CI runs from May 19, 2026 onward. Socket has published an active list of affected versions. Compare it against your full resolved dependency tree, not just your direct dependencies."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit lock files."})," Search for any AntV package, ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"echarts-for-react"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"timeago.js"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"size-sensor"}),", or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"canvas-nest.js"})," version published on or after May 19, 2026. If found, treat that installation and any credentials accessible from it as compromised."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate credentials immediately."})," If a potentially compromised install ran in a CI environment or on a machine with live cloud credentials, rotate those credentials now. Do not wait for forensic confirmation."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check for persistence."})," Look for unexpected entries in VS Code or Claude Code hook configurations, any unfamiliar"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"gh-token-monitor"})," ","services, and new GitHub Actions workflows in repositories that have npm publish access."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check transitive dependencies."})," You may not depend on AntV packages directly, but a charting component or UI kit you use might. Trace the full resolved tree in every affected repository."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Pin clean versions."})," Safe versions for AntV packages are those published before May 19, 2026. The npm release history for each package shows exact publish timestamps. Do not rely on the"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"latest"})," ","tag until npm has confirmed the malicious versions are unpublished."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"TeamPCP has moved through npm ecosystems in rapid succession, each time entering through a different compromised account. The question for teams is not whether they were hit by one specific incident, but whether they can answer that question for all of them quickly. Teams that have their full dependency graph mapped before an incident lands can scope the blast radius in minutes. Teams that trace manually spend that time on triage instead of remediation. Knowing what you install, and from whom, is the preparation that makes the difference."})]})},{id:"nginx-cve-2026-42945-rewrite-module-heap-overflow",title:"CVE-2026-42945: NGINX Rewrite Module Heap Overflow Enables Unauthenticated Code Execution",description:"CVE-2026-42945 (NGINX Rift) is a CVSS 9.2 heap buffer overflow in ngx_http_rewrite_module present since NGINX 0.6.27. An unauthenticated attacker can crash worker processes or achieve remote code execution on servers without ASLR.",date:"May 13, 2026",category:"Vulnerability Analysis",keywords:["CVE-2026-42945","NGINX Rift","nginx heap buffer overflow","ngx_http_rewrite_module vulnerability","nginx rewrite module flaw","NGINX remote code execution 2026","nginx unauthenticated RCE","PCRE capture nginx vulnerability","nginx worker crash loop","nginx heap overflow exploit","NGINX Plus R36 patch","nginx 1.30.0 CVE","depthfirst nginx disclosure","nginx security patch 2026","heap feng shui RCE"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On May 13, 2026, F5 
1Networks and the NGINX project published an advisory for"," ",(0,t.jsx)("a",{href:"https://nvd.nist.gov/vuln/detail/CVE-2026-42945",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"CVE-2026-42945"}),", a heap buffer overflow in"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ngx_http_rewrite_module"}),". The flaw has been present since NGINX"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.6.27"}),", a release from 2006, which means it spent eighteen years passing through production environments, security audits, and major version milestones without surfacing."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The attack requires no credentials and no prior access to the target. An unauthenticated attacker sends a crafted HTTP request, and the NGINX worker process overflows its heap. On servers running without ASLR, that overflow provides a path to remote code execution. On hardened systems with ASLR enabled, the worker crashes and restarts. Repeated requests can sustain that crash loop indefinitely."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Where the overflow originates"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["NGINX’s rewrite engine compiles rewrite directives into a small script that executes in two phases. The first phase calculates how much memory to allocate. The second phase copies data into that buffer. The vulnerability lives in a state inconsistency between these two phases, specifically in how the"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"is_args"})," ","flag is handled across them."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The length pass runs on a freshly initialized sub-engine where"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"is_args"})," ","starts at 0. No URI escaping is applied, so the calculated size reflects the raw capture length. The copy pass runs on the main engine, where a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"?"})," ","character in the replacement string has already set"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"is_args"})," ","to 1. At that point, the copy phase calls"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ngx_escape_uri"}),", which expands reserved characters into three-byte percent-encoded sequences. Characters counted as one byte during the length pass are written as three bytes during the copy pass. The buffer is too small."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The overflow writes attacker-controlled URI data past the end of the allocated heap region."," ",(0,t.jsx)("a",{href:"https://github.com/DepthFirstDisclosures/Nginx-Rift",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"DepthFirstDisclosures"}),", who responsibly disclosed this flaw, documented a full exploitation chain. Using heap feng shui across multiple requests, they position an"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ngx_pool_t"})," ","structure adjacent to the overflow target and corrupt its cleanup pointer. When NGINX destroys that pool, it calls whatever address the pointer now holds. POST request bodies deliver the payload past the null-byte restriction that URIs impose. The cleanup call becomes a call to"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"system()"}),"."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The trigger conditions are specific but common in real-world configurations: a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"rewrite"})," ","directive followed by a second"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"rewrite"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"if"}),", or"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"set"})," ","directive, using unnamed PCRE capture groups (",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"$1"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"$2"}),"), with a replacement string that includes a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"?"}),". That combination is a routine pattern in configurations that rewrite paths to include query strings."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What is affected"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The vulnerability covers every NGINX release from"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.6.27"})," ","through the current stable line. Fixed releases are available now."]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"NGINX Open Source 0.6.27–1.30.0:"})," fixed in"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.30.1"})," ","(stable) and"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.31.0"})," ","(mainline)"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"NGINX Open Source 0.6.27–0.9.7:"})," no fix planned; these releases are past end-of-technical-support"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"NGINX Plus R32–R36:"})," fixed in R32 P6 and R36 P4"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why this one is worth understanding"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The eighteen-year lifespan is notable, but the reason it lasted that long is more instructive than the number itself. The bug does not live in the regex engine, and does not live in the URI escaping function. Both components work correctly in isolation. The error lives in the handoff between them, where state that the main engine accumulates during directive processing is invisible to the fresh sub-engine used for length calculation. Neither pass looks obviously wrong on its own."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"ngx_http_rewrite_module"}
1)," ","is not a peripheral feature of NGINX. It is a core routing primitive that most non-trivial configurations rely on. Bugs in central surface areas persist precisely because they look like ordinary configuration until the exact combination of directives appears in a specific request."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Patching is straightforward for teams on supported versions. The more useful question is which deployments are actually running vulnerable configurations."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Upgrade NGINX Open Source"})," to"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.30.1"})," ","or"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.31.0"}),". Upgrade NGINX Plus to R32 P6 or R36 P4."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit your rewrite configurations."})," Search for unnamed PCRE captures (",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"$1"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"$2"}),") paired with replacement strings that include a"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"?"}),", followed by a second"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"rewrite"}),","," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"if"}),", or"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"set"})," ","directive. That is the exact trigger pattern."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Apply the configuration workaround if patching is not immediately possible."})," Replace unnamed captures with named captures using"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"(?P<name>...)"})," ","syntax and reference them as"," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"$name"})," ","in the replacement string. Named captures do not use the positional variable mechanism that causes the state inconsistency."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check ASLR status on NGINX servers."})," Without ASLR, the overflow is more directly exploitable for code execution. With ASLR, the primary risk is a crash loop on worker processes."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Plan migration for any instance on 0.6.27–0.9.7."})," No patch is planned for those releases. Moving to a supported version is the only remediation path."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"CVE-2026-42945 is a useful prompt to revisit how rewrite configurations are reviewed across your fleet. The trigger conditions are auditable with a grep across NGINX config files. Teams that have that inventory are minutes away from knowing their exposure. Teams that rely on manual inspection across distributed deployments face a broader triage problem that this CVE only partly illuminates. The next flaw with a narrow trigger and an eighteen-year history may arrive without a configuration-level workaround to buy time while patching catches up."})]})},{id:"tanstack-mistral-mini-shai-hulud-supply-chain",title:"TanStack and Mistral npm Packages Compromised in Mini Shai-Hulud Supply Chain Attack",description:"On May 11, 2026, a self-propagating npm worm infected 84 package versions across the @tanstack and @mistralai namespaces, along with over a dozen others. Here is how the attack worked, what was hit, and what to do if you installed any of these packages today.",date:"May 11, 2026",category:"Supply Chain Security",keywords:["TanStack supply chain attack","mini-shai-hulud npm worm","npm supply chain attack 2026","TanStack compromised","Mistral npm package compromised","@tanstack/react-router malware","@mistralai npm attack","npm worm credential stealer","TeamPCP supply chain","SLSA attestation bypass","preinstall script attack","GitHub Actions secret theft","supply chain security","npm security incident","dependency confusion attack"],content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On May 11, 2026, at approximately 19:20 UTC, a wave of malicious npm package versions began appearing in the registry. Within six minutes, 84 package artifacts had been published across the ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@tanstack"})," namespace. What followed was quickly confirmed as the latest wave of Mini Shai-Hulud, a self-propagating supply chain worm attributed to a group called TeamPCP, with damage extending well beyond TanStack alone."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["TanStack packages like ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@tanstack/react-router"})," see over 12 million weekly downloads. The Mistral AI SDK is installed across a significant share of AI-integrated Node.js applications. If you ran ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"npm install"})," against the ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"latest"})," tag on any of these packages today, there is a good chance you pulled in something you did not intend."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the worm gets in"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The entry point is a standard npm feature: ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"preinstall"})," scripts. When you install a package that defines a ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"preinstall"})," hook, npm runs that script automatically before placing the package into ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"node_modules"}),". No prompt, no confirmation. It just runs."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The compromised versions used that hook to download and install the Bun JavaScript runtime. Bun sidesteps the monitoring and logging that typically wraps Node.js process execution in CI environments, and the choice appears deliberate. Once Bun was in place, it executed a 2.3 MB obfuscated payload embedded in the package itself."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The whole sequence, from ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"npm install"})," to payload execution, happens silently, in the background, before your build even starts."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What the payload does"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The obfuscated payload is a credential harvesting engine with two jobs: steal everything it can find, then spread."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"It reads GitHub Actions runner process memory to extract environment secrets, then walks over 100 file paths looking for credentials across cloud providers (AWS IMDS, Secrets Manager, SSM; HashiCorp Vault; Kubernetes service accounts), cryptocurrency wallets, AI developer tools, and messaging applications. Whatever was accessible to the process running your install step, it tried to take."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Exfiltration routes the harvested data through two channels: the Session Protocol decentralized messaging network, with the full Session protocol stack bundled inside the payload, and GitHub’s own GraphQL API. Through the GraphQL channel, the worm authors dead-drop stolen data in commits disguised as Dependabot dependency updates, using branch names drawn from the Dune universe."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"To spread, the payload steals the npm OIDC token available in the GitHub Actions environment and uses it to publish infected versions of every package the compromised maintainer controls. That is how 84 artifacts appeared within six minutes: one maintainer account was enough to create the cascade."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The payload also installs persistence hooks into Claude Code, VS Code, and OS-level services that survive reboots. On a developer workstation, the exposure window is considerably longer than on a clean CI runner."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What makes this one different"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This wave of Mini Shai-Hulud is the first documented npm worm to produce validly-attested malicious packages. The compromised packages carry valid SLSA Build Level 3 provenance attestations, a mechanism designed to give users confidence that a package was built from a known source with a trusted pipeline."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The worm published through the legitimate GitHub Actions pipelines of the accounts it compromised, using stolen OIDC tokens. The attestations are genuine. They attest to a build pipeline that had already been taken over. Provenance attestations verify the build process; they say nothing about whether the actor running that pipeline still has control of their account. This incident draws a clear line between those two things."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What was compromised"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The confirmed affected namespaces and packages include:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"@tanstack:"})," 42 packages, 84 versions, including ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@tanstack/react-router"})," and related packages published May 11, 2026"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"@mistralai/mistralai:"})," versions 2.2.2, 2.2.3, 2.2.4"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"@mistralai/mistralai-azure:"})," versions 1.7.1, 1.7.2, 1.7.3"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"@mistralai/mistralai-gcp:"})," versions 1.7.1, 1.7.2, 1.7.3"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Other affected namespaces:"})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@squawk"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@uipath"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@tallyui"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@beproduct"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@draftlab"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@draftauth"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@taskflow-corp"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@tolka"}),", and several unscoped packages"]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"TanStack maintainers moved quickly. Tanner Linsley confirmed the compromise on X and the team began running unpublish scripts and shutting down their publishing pipelines within hours of detection. That work was underway on the same evening the attack hit."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If you run any of the affected packages, the steps are reasonably straightforward. All of them need to happen, not just the first."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check your lock file immediately."})," If your ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"package-lock.json"})," or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"yarn.lock"})," pins any ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@tanstack"})," or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@mistralai"})," package version published on May 11, 2026, treat that installation as compromised."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Pin to a pre-compromise version."})," For TanStack packages, the last safe versions are those published before May 11, 2026. Check the npm release history for each package. For Mistral, avoid 2.2.2–2.2.4 and 1.7.1–1.7.3 across the Azure and GCP variants."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate all CI/CD secrets immediately."})," GitHub Actions secrets, AWS credentials, Vault tokens, Kubernetes service account keys. Assume anything accessible to a process running on the affected runner is compromised. Rotate first, investigate after."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit GitHub Actions logs"})," for unexpected Bun installations, outbound connections to Session Protocol infrastru
1cture, or Dependabot-styled commits you did not initiate."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"If the install ran on a developer machine,"})," check for persistence hooks in ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/.claude/"}),", VS Code extension directories, and OS-level startup services. The payload explicitly targets those locations."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit transitive dependencies."})," You may not directly depend on ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@tanstack/router"}),", but something you depend on might. Check the full resolved dependency tree, not just your direct dependencies."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Re-examine packages published from your own accounts today."})," If a compromised package infected a CI pipeline you share with your own npm account, the worm may have used your publishing credentials too."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The credential rotation step is the one most likely to get skipped in the rush to pin the right package version. Pinning the dependency stops further infection. Rotating credentials closes the window on whatever was already taken."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This incident also surfaces a broader preparedness gap. Knowing that TanStack was compromised is easy once the reports are public. Knowing whether your specific lock file, across every service and monorepo your team runs, pulled in any of the 84 affected artifacts through transitive paths two or three hops deep is a different problem entirely. Teams that had complete dependency inventory across their builds were able to answer that question in minutes. Teams that had to trace dependencies manually spent hours on triage that could have been spent on remediation."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The pattern of Mini Shai-Hulud suggests future waves are likely. Having your dependency graph mapped before an incident lands is what turns a multi-hour fire drill into a focused, bounded response."})]})},{id:"aspnet-core-cve-2026-40372",title:"Microsoft Patches Critical ASP.NET Core DataProtection Flaw That Breaks Cryptographic Signatures",description:"CVE-2026-40372 is a CVSS 9.1 regression in Microsoft.AspNetCore.DataProtection that discards HMAC validation entirely on non-Windows systems. An attacker can forge auth cookies, decrypt protected payloads, and issue themselves valid tokens. Here is what happened, who is affected, and what to do right now.",date:"April 23, 2026",category:"Vulnerability Analysis",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["On April 23, 2026, Microsoft released an out-of-band emergency patch for CVE-2026-40372, a critical regression in the ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Microsoft.AspNetCore.DataProtection"})," NuGet package. The vulnerability carries a CVSS v3.1 score of 9.1 and its vector tells you most of what you need to know: no authentication required, no user interaction, accessible over the network."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The DataProtection API is how ASP.NET Core protects authentication cookies, antiforgery tokens, session state, password reset links, and OIDC state parameters. When that layer fails silently, an attacker does not need to find a separate injection point. The protection mechanism itself becomes the vulnerability."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What broke, technically"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The flaw is a regression in the managed authenticated encryptor, classified as CWE-347: Improper Verification of Cryptographic Signature. Two distinct failure modes exist in the affected build:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:["The HMAC validation tag is computed over the ",(0,t.jsx)("strong",{children:"wrong bytes of the payload"}),", meaning the integrity check runs but checks the wrong data."]}),(0,t.jsxs)("li",{children:["In some code paths, the computed hash is ",(0,t.jsx)("strong",{children:"discarded entirely"})," before the comparison step, bypassing integrity verification completely."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The practical consequence is that an attacker who can observe a valid protected payload - say, an authentication cookie - can modify it and resubmit it without the server detecting the tampering. With a bit more work, they can craft entirely new payloads and have them accepted as legitimate by the application."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This is not an exploit that requires sophisticated tooling. Any HTTP client and a working understanding of the DataProtection format is sufficient once the integrity check is gone."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Who is affected"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The vulnerability is narrow in its version scope but broad in its impact for those who hit it:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Affected package:"})," ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Microsoft.AspNetCore.DataProtection"})," versions 10.0.0 through 10.0.6"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Platform restriction:"})," The regression only manifests on ",(0,t.jsx)("strong",{children:"non-Windows operating systems"})," - Linux and macOS deployments"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Fixed version:"})," 10.0.7 or later"]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The Windows exclusion may feel like a relief for some teams, but it is worth pausing on. The majority of production ASP.NET Core deployments in the last two years have shifted toward Linux containers. If your application runs in Docker, Kubernetes, or any Linux-based cloud runtime, the platform restriction does not protect you."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The affected package version also has broad blast radius through transitive dependencies. You may not have directly declared ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Microsoft.AspNetCore.DataProtection"})," in your project, but if any of your dependencies pulled in 10.0.6, you are running the vulnerable code at runtime."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What an attacker can do with this"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The full exploitation surface is significant. DataProtection underpins several mechanisms in a typical ASP.NET Core application:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Authentication cookies"})," - forge a session for any user, including administrators, without knowing their password"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Antiforgery tokens"})," - bypass CSRF protections on state-changing endpoints"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Password reset and email confirmation links"})," - generate valid tokens for arbitrary accounts"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"OIDC state parameters"})," - manipulate OAuth flows to redirect authentication to attacker-controlled endpoints"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"TempData payloads"})," - tamper with server-side state passed between requests"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Decryption of previously captured traffic"})," - if an attacker archived protected payloads from the vulnerable window, those can now be decrypted"]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The most critical scenario is authentication cookie forgery. An attacker who knows the user identifier for an admin account - often just an email address or a sequential integer - can construct a valid session cookie without ever interacting with the login endpoint. No credentials, no brute force, no phishing required."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What to do right now"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The patch is available and upgrading is the only real fix. But patching alone is not sufficient if your application was exposed during the vulnerable window."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Upgrade immediately"})," to ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Microsoft.AspNetCore.DataProtection"})," 10.0.7 or later"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit transitive dependencies"})," - check your lock file for any package that pulls in the vulnerable version, not just direct references"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate the DataProtection key ring"})," - tokens issued during the vulnerable window remain cryptographically valid after the upgrade unless you rotate keys. Existing sessions, password reset links, and OIDC tokens all need to be invalidated"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Force reauthentication"})," for all active sessions, particularly those with elevated privileges"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit long-lived tokens"})," - password reset links and API tokens issued between the deployment of 10.0.0 and the patch have unknown integrity and should be expired"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Review authentication logs"})," for unusual session creation patterns, especially sessions that do not correspond to a preceding login event"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate application secrets"})," stored as DataProtection payloads - connection strings, API credentials, or any value your application protected with the API during the exposure window"]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The key rotation step is the one most teams will skip. It is also the step that matters most. Upgrading to 10.0.7 stops new forgeries. Rotating the key ring invalidates anything that may have been forged before you patched."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The regression problem"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Something worth noting about the nature of this vulnerability: it is a regression, not a design flaw. The DataProtection API worked correctly before 10.0.0. Something introduced in that version broke the HMAC validation in a way that was not caught before release and was not caught through six subsequent patch versions."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Cryptographic code is notoriously difficult to regression-test because incorrect implementations often look correct at the unit test level. A test that checks whether a payload roundtrips successfully through protect and unprotect will pass even when the HMAC is computed over the wrong bytes - the payload still decrypts, the test still passes, and the integrity violation is invisible."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Catching this class of bug requires adversarial tests: can a tampered payload be accepted? Can a payload forged without access to the key be verified? Those tests are rarely written because developers tend to test the happy path. This incident is an argument for making adversarial cryptographic tests a first-class part of any security-critical library’s test suite."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Where Prismor fits"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"When a vulnerability like this lands, the first question is not “are we using ASP.NET Core?” - most teams know that. The harder question is: which services are running 10.0.6 specifically, on Linux, and were they internet-facing during the exposure window?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Answering that requires knowing your dependency graph across every service and deployment, not just the ones someone remembers to check. The window between “patch released” and “every affected 
1instance actually updated” is where the real risk lives. And for transitive dependencies, that window is longer because teams frequently do not realize they are carrying the vulnerable version at all."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Inventory is what closes that window. Knowing what is running, where, and with which dependency versions is what turns a fire drill into a twenty-minute remediation."}),(0,t.jsxs)("p",{className:"text-gray-500 leading-relaxed mb-4 font-medium text-base",children:["Source: ",(0,t.jsx)("a",{href:"https://github.com/dotnet/announcements/issues/395",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"dotnet/announcements — CVE-2026-40372 ASP.NET Core DataProtection Privilege Escalation Vulnerability"})]})]})},{id:"vercel-oauth-breach-april-2026",title:"Vercel got breached. Here is what that means for everyone downstream.",description:"Vercel confirmed unauthorized access to internal systems on April 19, 2026, while a BreachForums listing claims source code, GitHub tokens, and NPM credentials are for sale. Here is what we know, what it means, and what to do now.",date:"April 19, 2026",category:"Incident Analysis",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"On Sunday morning, Vercel confirmed what a lot of people on X had been whispering about since the night before. Somebody got into their internal systems. The company put out a short security bulletin, pulled in outside incident responders, notified law enforcement, and told a “limited subset” of affected customers directly."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"If you have never thought about deployment platforms as supply chain risk, this is the week to start."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The short version of what happened"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Vercel published a short ",(0,t.jsx)("a",{href:"https://vercel.com/kb/bulletin/vercel-april-2026-security-incident",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"security bulletin"})," on their knowledge base. They confirmed unauthorized access to certain internal Vercel systems, said services remain operational, and pointed customers at the sensitive environment variable feature as a mitigation. The bulletin also names a single indicator of compromise: a third-party AI tool’s Google Workspace OAuth app, ID ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200 text-base",children:"110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com"}),", which Vercel describes as the origin of the incident and flags for broader community investigation. That is basically the whole official disclosure."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The unofficial version, pieced together from the BreachForums listing and reporting from BleepingComputer and Decipher, is a lot louder."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"An actor posting under the ShinyHunters name put Vercel data up for sale at around $2 million. The listing claims to include internal database records, employee account access, source code, GitHub tokens, NPM tokens, API keys, and access to internal deployments. As proof, the seller reportedly dumped a sample of 580 employee records pulled from Vercel’s internal Linear workspace, complete with names, Vercel emails, account statuses, and activity timestamps, plus a screenshot of an internal enterprise dashboard."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Worth flagging: BleepingComputer reports that established members of the ShinyHunters crew have denied involvement, which means the name on the listing may be borrowed rather than authentic. The data being real and the brand being spoofed are not mutually exclusive."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Theo Browne (t3.gg) posted early analysis suggesting that Vercel’s Linear and GitHub integrations took the brunt of the intrusion, and that environment variables flagged as “sensitive” (which Vercel stores encrypted and separated from standard env vars) appear to have held up. Standard, non-sensitive env vars did not get that same protection."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Vercel has not confirmed the attack vector. No timeline of when the initial access happened. No breakdown of what “limited subset” means in customer-count terms. That gap in the official story is part of why the industry reaction has been sharp."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why this is not just a Vercel problem"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Here is the thing about modern deployment platforms. You hand them your source, your build pipeline, and your secrets, and in exchange they give you speed. That tradeoff makes sense right up until the platform itself becomes the attack surface."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Vercel sits in the middle of a huge chunk of the JavaScript ecosystem. They maintain Next.js. Their customers include crypto frontends, Web3 wallet interfaces, SaaS dashboards, and marketing sites for companies you have heard of. A single compromised path inside Vercel can touch:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Customer source code sitting in connected GitHub repos"}),(0,t.jsx)("li",{children:"Environment variables (database URLs, third party API keys, auth secrets)"}),(0,t.jsx)("li",{children:"Deployment pipelines that push production code"}),(0,t.jsx)("li",{children:"NPM publishing credentials for packages Vercel maintains or participates in"}),(0,t.jsx)("li",{children:"Internal tickets in Linear that describe ongoing security work, unpatched bugs, and architectural decisions"})]}),(0,t.jsxs)("figure",{className:"my-8 mx-auto max-w-sm",children:[(0,t.jsx)("img",{src:"/vercel-npm-package-reach.png",alt:"Bar chart of weekly npm downloads for Vercel-maintained packages, led by next at roughly 27 million, followed by @next/swc-linux-x64-gnu and @next/swc-linux-x64-musl, then styled-jsx, swr, turbo, the AI SDK, @vercel/analytics, @next/swc-darwin-x64, and @vercel/node",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Weekly npm downloads for packages Vercel maintains. A compromised NPM token with write access to any one of these is a supply chain event that reaches tens of millions of installs a week."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If even a fraction of the claimed token set is real and usable, the blast radius goes way past Vercel’s own perimeter. A valid GitHub token with write access to a popular package repo lets an attacker plant a malicious commit. A valid NPM token lets them publish a poisoned version of a dependency that thousands of downstream projects will pull on their next install. That is textbook supply chain compromise, and it is the nightmare scenario people are talking about when they say “massive ripple effects.”"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"To be clear, as of the afternoon of April 19, nobody has shown public evidence of a malicious package publish or a tampered release tied to this incident. The supply chain risk is probable rather than confirmed. But the confirmed part, the internal breach itself, is already enough to justify a pretty aggressive response from anyone with credentials connected to Vercel."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What the “sensitive env var” detail actually tells us"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Vercel’s public re
1commendation to review environment variables and use the sensitive variable feature is doing a lot of work in a short paragraph."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The feature exists because regular env vars on Vercel live in a readable form for build and runtime processes, while sensitive ones are encrypted and access-gated. If the attackers got into systems where standard env vars were visible, any secret a team pasted into the dashboard without ticking the sensitive box is potentially exposed. API keys for Stripe, database passwords, private RPC endpoints, third party auth tokens, you name it."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is the part that affects customers directly, regardless of what happens with the larger supply chain question. If you deploy on Vercel, you need to assume every non-sensitive env var you have set at any point could be in the wrong hands and act on that assumption now."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What to do right now if you deploy on Vercel"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Review the activity log on your Vercel account and environments for anything you do not recognize."}),(0,t.jsx)("li",{children:"Rotate every environment variable that was not marked sensitive. Do not wait for a notification email, do it now."}),(0,t.jsx)("li",{children:"Regenerate any GitHub, NPM, database, payment processor, or third party API credential that was ever pasted into a Vercel project."}),(0,t.jsx)("li",{children:"Turn on the sensitive env var feature for everything going forward that qualifies."}),(0,t.jsx)("li",{children:"Check your build logs for secrets that may have been echoed into output."}),(0,t.jsx)("li",{children:"If you publish NPM packages through a workflow that touches Vercel infrastru
1cture, audit recent publishes and consider revoking and reissuing tokens."}),(0,t.jsx)("li",{children:"Look at your connected GitHub integration and check for any unusual commits, new deploy keys, or outbound webhooks you did not add."})]})]})},{id:"nist-nvd-cve-prioritization-2026",title:"When the System Built to Warn Us Can No Longer Keep Pace",description:"NIST is moving to risk-based CVE enrichment prioritization. Not every vulnerability will get the full treatment anymore. Here is what changed, why, and what your security team should do about it.",date:"April 15, 2026",category:"Vulnerability Intelligence",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"When a software vulnerability is discovered, it gets assigned a CVE (Common Vulnerabilities and Exposures) ID by a CVE Numbering Authority, or CNA. Think of CNAs as the people who stamp and file the paperwork: software vendors, research organizations, and security firms that are authorized to officially name and record vulnerabilities."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Once a CVE exists, NIST’s National Vulnerability Database (NVD) takes over and enriches it. That enrichment is the valuable part: severity scores (CVSS), affected product lists, and references that help security teams decide what to patch first. The NVD is essentially the annotated, searchable version of the CVE list that the security industry has relied on for over two decades."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/nist-nvd-cve-volume.png",alt:"Illustration showing CVE volume overwhelming the NVD, with a flood of vulnerability records pouring into a small processing box",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"CVE submissions have grown 263% since 2020, outpacing the NVD’s capacity to enrich them."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Big Backlog, Thanks to AI"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Starting in early 2024, the NVD fell behind on enriching CVEs. Badly behind. The volume of submissions had simply outpaced what the team could process. NIST worked faster than ever and enriched nearly 42,000 CVEs in 2025, which was 45% more than any prior year. It still was not enough."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"CVE submissions increased 263% between 2020 and 2025. Submissions in the first three months of 2026 are already running about a third higher than the same period last year. The trend is not slowing down. NIST had to make a choice: keep pretending they could enrich everything, or be transparent about what they can actually handle."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What Changes Today"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"As of April 15, 2026, NIST is moving to a risk-based prioritization model. Not every CVE will get the full enrichment treatment automatically. Instead, NIST will focus its resources on three categories:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:["CVEs that appear in ",(0,t.jsx)("strong",{children:"CISA’s Known Exploited Vulnerabilities (KEV) Catalog"}),", with a goal to enrich these within one business day"]}),(0,t.jsxs)("li",{children:["CVEs affecting ",(0,t.jsx)("strong",{children:"software used within the federal government"})]}),(0,t.jsxs)("li",{children:["CVEs for software defined as ",(0,t.jsx)("strong",{children:"“critical” under Executive Order 14028"})]})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Everything else gets filed under a new status called ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"Not Scheduled"}),". The CVE still exists in the NVD, it just will not be enriched unless someone requests it. You can email ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"})," to request enrichment of specific unscheduled vulnerabilities, and NIST will review those as resources allow."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"On top of that, NIST will no longer routinely provide its own separate severity score for CVEs where the submitting CNA already included one. And they will only reanalyze previously enriched CVEs if a modification materially changes the data, rather than reviewing all updates automatically."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Hello KEV, *Bookmarked*"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If there is one practical takeaway from all of this, it is this: CISA’s Known Exploited Vulnerabilities Catalog has effectively become the highest-priority enrichment queue in the NVD. NIST is committing to enrich KEV-listed vulnerabilities within one business day of receipt."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Bookmark this: ",(0,t.jsx)("a",{href:"https://www.cisa.gov/known-exploited-vulnerabilities-catalog",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"CISA Known Exploited Vulnerabilities (KEV) Catalog"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The KEV Catalog lists vulnerabilities that have confirmed, real-world exploitation. That makes it inherently actionable, and now it is also the thing NIST will process fastest. For any security team trying to triage what to patch first, that alignment is useful. If a CVE is on the KEV list, NIST treats it as top priority. If your team is not already using the KEV Catalog to guide patching decisions, now is the time to start."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Thoughts"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"NIST is not shrinking the NVD. All CVEs still get listed. But “listed” and “enriched” are no longer the same thing. If a CVE is not on the KEV Catalog, not used by the federal government, and not classified as critical software, it may sit unenriched for a while. Build your workflows accordingly."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The long-term goal is to develop automated enrichment systems that can handle the volume without relying entirely on manual analysis. But that work takes time. In the meantime, NIST is being upfront about the triage they are already doing. That kind of transparency, even when the news is not great, is actually a good sign for the long-term health of the program."}),(0,t.jsxs)("p",{className:"text-gray-500 leading-relaxed mb-4 font-medium text-base",children:["Source: ",(0,t.jsx)("a",{href:"https://www.nist.gov/news-events/news/2026/04/nvd-updates-nvd-operations-address-record-cve-growth",target:"_blank",rel:"noopener noreferrer",className:"text-amber-700 underline hover:text-amber-900",children:"NIST — NVD Updates NVD Operations to Address Record CVE Growth"})]})]})},{id:"tool-boundary-redaction-ai-agents",title:"Your AI Agent Remembers Your Secrets",description:"AI coding agents create permanent records of your API keys and tokens. We built a transparent redaction layer using hooks to stop the leaks without breaking the workflow.",date:"April 13, 2026",category:"Security for AI",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The practice of keeping sensitive keys in a .env file is a fundamental rule of modern development. It is the first line of defense that every developer learns. However, the rise of AI coding agents has introduced a subtle complication: keys are shared in agent chats and the agent might still end up creating a permanent record of those secrets elsewhere."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What We Found"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Even when a developer is careful to use a .env file, the moment a key is mentioned in a chat or read by the agent to debug a connection, it is recorded. We found thousands of lines of session data tucked away in hidden folders. Within these logs, API keys and access tokens were sitting in plain text, completely unencrypted and accessible to anyone who knows where to look."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/ai-agent-secrets-tweet-2.jpg",alt:"Terminal screenshots showing exposed API keys in history.jsonl and conversation logs",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Exposed API keys and tokens found in plain text inside conversation history and session logs."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Good Memory Costs Something"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"You might wonder why these tools keep such detailed records. It comes down to a feature called conversation lookup. To provide helpful follow-up answers, Claude needs to remember what happened earlier in your session. By saving this history locally, the tool ensures that it does not lose its train of thought if you restart your terminal."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The problem is that these records are typically stored in files like ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"history.jsonl"})," inside the ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/.claude"})," directory. Because AI agents transmit full conversation transcripts and tool outputs to their providers on every turn, any secret that enters the agent context becomes part of a long-lived on-disk artifact."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Verified Solution: Tool-Boundary Redaction"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"To fix this, we investigated using the internal hook system of the agent to create a transparent redaction layer. The goal is to allow the agent to use a secret locally while ensuring the real value never reaches the transcript or the API provider."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The real secret is resident only inside the PreToolUse process and the local subprocess; the model, the JSONL transcript, and the upstream API see only the placeholder."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The implementation works by teaching the model to use placeholders like ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"@@SECRET:stripe_key@@"}),". When the model tries to run a command, a series of invisible steps occur:"]}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:["A ",(0,t.jsx)("strong",{children:"PreToolUse hook"})," intercepts the command, looks up the real secret on your disk, and swaps the placeholder for the real value just before execution."]}),(0,t.jsxs)("li",{children:["To prevent the secret from leaking if the command prints it out, the hook wraps the entire command in a ",(0,t.jsx)("strong",{children:"sed filter"}),". This filter automatically scrubs the real secret out of the output and replaces it with the placeholder again before the model or the logs ever see it."]})]}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/ai-agent-secrets-tweet-3.jpg",alt:"Sequence diagram showing the flow between Model, Claude Code, PreToolUse hook, Bash, and JSONL/API - demonstrating how secrets are substituted and scrubbed",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"The redaction flow: the model only sees placeholders, while the real secret exists briefly in the local process."})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"In testing, this “happy path” produced zero leaks across multiple bash calls, as the real value only existed temporarily in the local process."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/ai-agent-secrets-tweet-4.jpg",alt:"Bar chart showing hook fire counts across test battery - PreToolUse and PostToolUse invocations for Bash, Write, Edit, Read, and Grep tools",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Hook fire counts across a single test session, showing consistent interception across all tool types."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How to Stop the Leaks"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Even with these hooks, secrets can still slip through if an operator types them manually into a prompt or narrations. To build a complete defense, we developed a multi-layered approach:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"PreToolUse & PostToolUse hooks:"})," Scripts to handle real-time tokenization and scrubbing."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Post-hoc cleanup:"})," Integrate a tool like ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-black underline underline-offset-4 hover:text-gray-600 transition-colors",children:"Sweep"}),", which acts as a post-hoc cleanup layer. It scans your agent caches for any residue that may have slipped through the hooks."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Session-end sweeps:"})," You can configure the agent to run a cleanup sweep automatically every time a session ends by using the PostStopSession hook."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Operational Discipline:"})," The most important step is to ensure that secret material is loaded into its designated directory outside of the agent session. If you never show the real secret to the model, the model can never accidentally repeat it."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"By combining real-time prevention with regular cleanup, you can cover about 95% of the risk surface and keep your development environment safe from accidental exposure."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Open Source"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["Our research is free and open-s
1ource: ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-black underline underline-offset-4 hover:text-gray-600 transition-colors",children:"github.com/PrismorSec/prismor"})]})]})},{id:"ai-agent-secrets-leak",title:"Your Home Directory is a Secret Goldmine for Attackers",description:"Keeping keys in a .env file is the first rule of development. But AI coding agents have introduced a subtle complication that most teams have not thought about yet.",date:"April 6, 2026",category:"Security for AI",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The practice of keeping sensitive keys in a .env file is a fundamental rule of modern development."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"It is the first line of defense that every developer learns. However, the rise of AI coding agents has introduced a subtle complication: keys are shared in agent chats and the agent might still end up creating a permanent record of those secrets elsewhere."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What We Found"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"While exploring the hidden corners of a local development environment, we discovered that AI agents are incredibly talkative."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Even when a developer is careful to use a .env file, the moment a key is mentioned in a chat or read by the agent to debug a connection, it is recorded."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"We found thousands of lines of session data tucked away in hidden folders. Within these logs, API keys and access tokens were sitting in plain text, completely unencrypted and accessible to anyone who knows where to look."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/blog-sweep.png",alt:"A terminal window showing the contents of history.jsonl with an exposed API key highlighted",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"A screenshot of history.jsonl showing an exposed API key sitting in plain text inside the ~/.claude directory."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Good Memory Costs Something"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"You might wonder why these tools keep such detailed records. It comes down to a feature called conversation lookup."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"To provide helpful follow-up answers, Claude needs to remember what happened earlier in your session. By saving this history locally, the tool ensures that it does not lose its train of thought if you restart your terminal."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["The problem is that these records are typically stored in a file called ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"history.jsonl"})," inside the ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/.claude"})," directory. Because this file is written in plain text, any secret that passes through the chat becomes a permanent part of your local storage."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Goldmine for Attackers"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"An attacker does not need to be a genius to exploit this. They do not have to manually browse your folders or guess y
1our passwords."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Instead, they can deploy a simple script that scans your home directory for patterns that look like API keys. In a matter of seconds, an automated script can harvest credentials for your cloud providers, payment gateways, and database internal tools."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Because these files are residue and live outside of your project folder, they are often missed by standard security audits. A single compromised laptop can quickly lead to a full breach of your entire infrastructure."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How to Protect Your Environment"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Security is a shared responsibility between the developer and their tools. You can stay safe by following a few simple practices."}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Use Environment Files:"})," Always keep your sensitive keys in a .env file."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Keep Secrets Out of Chat:"})," Never paste a raw API key directly into a conversation with an AI agent."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Scan for Residue:"})," Regularly check your AI configuration folders for leaked data."]})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["To make this easier, we made an open source tool called ",(0,t.jsx)("a",{href:"https://github.com/PrismorSec/prismor",target:"_blank",rel:"noopener noreferrer",className:"text-black underline underline-offset-4 hover:text-gray-600 transition-colors",children:"Sweep"}),", part of the Prismor repo. Sweep is designed to find these hidden leaks in your AI tool configurations. Instead of just deleting your history, it moves any found secrets into an encrypted vault."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The Vault Model"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("a",{href:"/docs/sweep",className:"text-black underline underline-offset-4 hover:text-gray-600 transition-colors",children:"Sweep"})," does not simply delete your history. It moves every found secret into a single encrypted file: ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"~/.prismor/sweep.vault.enc"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Every time a redaction runs, the secret and its exact location - file, line, column - gets appended to this vault. A passphrase is required to open it for both writing and reading."}),(0,t.jsx)("pre",{className:"bg-gray-900 text-white border border-gray-700 rounded-lg p-4 mb-6 overflow-x-auto text-sm leading-relaxed",children:`┌─────────────────────────────────────────────────┐
2│  sweep.vault.enc  (AES-256, user passphrase)    │
3│                                                  │
4│  { file, line, col, secret, rule, redacted_at } │
5│  { file, line, col, secret, rule, redacted_at } │
6│  { file, line, col, secret, rule, redacted_at } │
7│  ...accumulates across runs...                   │
8└─────────────────────────────────────────────────┘`}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The vault is protected using AES-256-CBC encryption and is accessible only with a passphrase that you create. This ensures that your AI tools can function properly while your actual secrets remain unreadable to any malicious scripts scanning your machine."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"By moving these keys into an encrypted space, you can take advantage of AI assistance without leaving your credentials exposed in plain text."})]})},{id:"axios-npm-supply-chain-compromise",title:"When a core npm dependency becomes the attack path: lessons from the Axios compromise",description:"A short practical look at the recent Axios npm compromise, why it matters for engineering teams, and what to do next.",date:"March 31, 2026",category:"Supply Chain Security",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Most engineering teams trust Axios without thinking twice."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"It is one of the most common packages in the JavaScript ecosystem. It shows up in frontend apps, backend services, CLIs, internal tools, and AI workflows."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That is 
8what made the recent Axios incident so important."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-bold text-lg lg:text-xl",children:"What happens when a package that feels completely routine suddenly becomes the attack path?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is the supply chain lesson here."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"ELI5: what does Axios actually do?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Axios is a JavaScript library that helps apps talk to other apps over the internet."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"In simple terms, if your frontend needs to fetch data from an API, or your backend needs to call another service, Axios is often the tool making that request."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"It is commonly used for things like:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"loading user data in a web app"}),(0,t.jsx)("li",{children:"sending form submissions"}),(0,t.jsx)("li",{children:"calling internal APIs between services"}),(0,t.jsx)("li",{children:"connecting apps to external platforms like Stripe, OpenAI, GitHub, or Slack"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is why it is everywhere. If a package like Axios gets compromised, it can land in a lot of places very quickly because so many teams install it as part of normal development."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/axios-downloads.png",alt:"Axios npm package showing 101 million weekly downloads, version 1.14.0, MIT license",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"Axios has over 101 million weekly downloads on npm, making it one of the most widely installed JavaScript packages."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What happened"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"On March 31, 2026, two malicious Axios versions were briefly published to npm:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"})}),(0,t.jsx)("li",{children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"})})]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Public reporting indicates this happened after a maintainer account was compromised. The malicious releases added a dependency, ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"}),", which was not part of normal Axios behavior and was identified as the delivery path for malware. Security researchers described the payload as a cross-platform remote access trojan affecting macOS, Linux, and Windows."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The bad releases were removed quickly, but any environment that pulled them during the live window should be treated as potentially compromised."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:'Community warnings spread fast because this kind of attack lands exactly where developers move quickly. One Reddit post aimed at Claude users put it simply: if you were "vibe coding" and ran fresh installs without checking, you should review your lockfiles immediately.'}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A package like Axios can reach:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"developer laptops"}),(0,t.jsx)("li",{children:"CI runners"}),(0,t.jsx)("li",{children:"production builds"}),(0,t.jsx)("li",{children:"internal tools"}),(0,t.jsx)("li",{children:"generated code from AI assistants"}),(0,t.jsx)("li",{children:"container images built from fresh installs"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is 
8what makes this kind of compromise dangerous. The issue is not only that a package was bad for a short period of time. It is that the package sits in places teams trust by default."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the attack was constructed"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This was not a typosquat or a rogue transitive dependency slipping into a build. The attacker had direct publishing access to the official Axios package on npm, likely through a compromised maintainer account. According to a collaborator in the official GitHub issue thread, the suspected compromised account belonged to a maintainer whose repository permissions were higher than those of other collaborators, which made rapid remediation harder."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["No Axios source files were modified directly. Instead, the attacker added a pre-staged malicious dependency, ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"}),", to the ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"package.json"})," of the new Axios releases. The ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"plain-crypto-js"})," package was purpose-built for this attack: a clean version (",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"4.2.0"}),") had been published 18 hours earlier, likely to give it a brief history on the registry and avoid suspicion. Version ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"4.2.1"})," contained the actual payload."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["When a developer or CI system runs ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"npm install [email protected]"}),", npm resolves the dependency tree, pulls ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"}),", and automatically executes its ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"postinstall"})," hook: ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"node setup.js"}),". That single script execution is where the compromise begins."]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The dropper: double-obfuscated and self-erasing"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"setup.js"})," postinstall dropper used two layers of obfuscation to avoid static analysis: reversed Base64 encoding with padding character substitution, and an XOR cipher with a hardcoded key and constant value. The goal was to make the payload invisible to automated scanners parsing for known malicious patterns."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Once deobfuscated, the script detects the host operating system and reaches out to a command-and-control server to download a second-stage payload appropriate for the platform. This is what security researchers identified as a cross-platform remote access trojan."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:["After execution, the malware cleans up after itself. It deletes ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"setup.js"}),", removes the ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"package.json"}
8)," that contained the postinstall hook, and replaces it with a clean file that was pre-staged as ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"package.md"}),". If you inspected ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"node_modules/plain-crypto-js"})," after the fact, you would find no obvious sign that a postinstall script had ever been there. That is what makes this particular attack harder to catch through manual review alone."]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do right now"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If your team uses Axios, the safest move is to check immediately."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Start with the basics:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:["Do not use ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.14.1"})," or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.30.4"})]}),(0,t.jsx)("li",{children:"Check lockfiles, build logs, and recent installs for those versions"}),(0,t.jsxs)("li",{children:["Look for ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"[email protected]"})," in dependency trees or build artifacts"]}),(0,t.jsx)("li",{children:"Audit CI jobs, containers, and developer machines that may have pulled fresh installs during the affected window"}),(0,t.jsx)("li",{children:"Rotate any secrets that may have been available in those environments"}),(0,t.jsx)("li",{children:"Review unusual outbound network activity or suspicious processes after install"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"If those versions were installed in CI, on a developer laptop, or in a build container, it is safest to assume credentials in that environment may have been exposed until proven otherwise."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This incident is a reminder that highly trusted packages deserve the same level of attention as high-trust infrastru
8cture."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A common HTTP client may look harmless because it is familiar. But when it sits across apps, services, and build pipelines, a compromise can spread quickly through normal engineering activity."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That is why teams should be stricter about:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"pinning and reviewing dependency updates before broad rollout"}),(0,t.jsx)("li",{children:"using lockfiles consistently across local and CI environments"}),(0,t.jsx)("li",{children:"watching for unexpected new transitive dependencies"}),(0,t.jsx)("li",{children:"limiting secrets available during install and build steps"}),(0,t.jsx)("li",{children:"treating fresh installs in CI as part of the attack surface"})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Add one simple defense today: delay brand-new package versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This is one of the best practical tips from the Reddit threads today."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Set a minimum release age or cooldown before your builds accept freshly published packages. Example shared by developers:"}),(0,t.jsx)("pre",{className:"bg-gray-900 text-white border border-gray-700 rounded-lg p-4 mb-6 overflow-x-auto text-sm ",children:(0,t.jsx)("code",{children:"npm config set min-release-age 3"})}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:'That means a package has to be at least a few days old before it gets pulled automatically. It will not stop everything, but it helps a lot against "compromised maintainer publishes malicious version for 2 hours" type attacks.'}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Takeaway"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The Axios incident is a reminder that even the most familiar package can become a supply chain event very quickly."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["When something like this happens, the first real question becomes: ",(0,t.jsx)("strong",{children:"what is the blast radius?"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Which repos pulled it? Which lockfiles captured it? Which containers baked it in? Which CI jobs installed it? Which developer machines ran it? Which secrets were present at the time?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is where visibility matters. In Prismor, this is the kind of question teams should be able to answer quickly through the inventory view: where a package version exists, which repos and services depend on it, what environments it reached, and how far exposure can spread once trust breaks."})]})},{id:"litellm-pypi-supply-chain-compromise",title:"When the AI dependency becomes the attack path: lessons from the LiteLLM PyPI compromise",description:"A short practical look at the recent LiteLLM PyPI compromise, why it matters for AI infrastructure teams, and what to do next.",date:"March 24, 2026",category:"Supply Chain Security",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If you build with AI tooling today, you probably move fast."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"You install wrappers, SDKs, gateways, agent frameworks, and helper libraries without thinking too much about it. That is normal. It is how modern teams ship."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"But the recent LiteLLM incident is a reminder that AI infrastru
8cture now carries the same supply chain risk as the rest of software."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-bold text-lg lg:text-xl",children:"What happens when a dependency sitting in the middle of your LLM stack becomes the attack path?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is what made this incident worth paying attention to."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What happened"}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["Multiple community reports flagged that ",(0,t.jsxs)("strong",{children:["LiteLLM versions ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.82.7"})," and ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.82.8"})," on PyPI were compromised"]})," and should not be installed. A Hacker News post described suspicious behavior immediately after install, including severe resource usage and a payload added into ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"proxy_server.py"})," that decoded and executed another file. A commenter also warned that in ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.82.8"}),", even importing the package could trigger the malicious behavior."]}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The same warning quickly showed up in the community around AI infrastructure. A Reddit thread in ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"r/LocalLLaMA"})," explicitly told users not to update to ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.82.7"})," or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.82.8"}),", and pointed to an incident write-up describing it as a supply chain attack."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That matters because LiteLLM is often used as a central piece of LLM infrastructure across applications, gateways, agent systems, and internal AI platforms."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["The release contains a malicious ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:".pth"})," file (",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"litellm_init.pth"}),") that executes automatically on every Python process startup when LiteLLM is installed in the environment. No corresponding tag or release exists on the LiteLLM GitHub repository - the package appears to have been uploaded directly to PyPI, bypassing the normal release process."]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Kudos to PyPI for taking quick action on this. The affected versions were quarantined promptly, preventing further installs while the investigation continued."}),(0,t.jsxs)("figure",{className:"my-8",children:[(0,t.jsx)("img",{src:"/litellm.png",alt:"PyPI quarantine notice for LiteLLM 1.82.8 - the project has been quarantined and is not installable by clients",className:"w-full rounded-lg border border-gray-200 shadow-sm"}),(0,t.jsx)("figcaption",{className:"text-base text-gray-500 mt-3 text-center font-medium",children:"PyPI quarantined the compromised LiteLLM versions, blocking further installs."})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why this matters"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"AI tooling often gets trusted faster than traditional infrastru
8cture."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"A team might pin a database driver carefully, but casually upgrade an LLM wrapper because it feels like application code. In reality, tools like LiteLLM can sit close to the most sensitive parts of an AI stack:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Provider API keys"}),(0,t.jsx)("li",{children:"Internal prompts and context"}),(0,t.jsx)("li",{children:"Model routing rules"}),(0,t.jsx)("li",{children:"Usage and billing controls"}),(0,t.jsx)("li",{children:"MCP and tool integrations"}),(0,t.jsx)("li",{children:"Internal gateways"}),(0,t.jsx)("li",{children:"Developer laptops"}),(0,t.jsx)("li",{children:"CI runners"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is what makes incidents like this dangerous. The compromise is not only about one bad package version. It is about the trust that package inherits."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do right now"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If your team uses LiteLLM, the safest move is to investigate immediately."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Start with the basics:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:["Do not install or use ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.82.7"})," or ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"1.82.8"})]}),(0,t.jsx)("li",{children:"Check lockfiles, build logs, and recent installs for those versions"}),(0,t.jsx)("li",{children:"Audit CI jobs, containers, and developer machines that may have pulled them"}),(0,t.jsx)("li",{children:"Rotate any model provider API keys or secrets that may have been accessible"}),(0,t.jsx)("li",{children:"Review unusual outbound activity or unexpected process execution after install or import"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The key point is simple: if those versions touched an environment with secrets, assume those secrets may be exposed until proven otherwise."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The bigger lesson"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This is a reminder that AI infrastructure has become part of the software supply chain, and it needs to be treated with the same discipline as any other high-trust component."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:'Many teams still think about AI libraries as "just developer tooling" or "just a wrapper."'}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"But a package that can proxy requests to multiple model providers, sit in the request path for agent systems, manage keys and routing, and run in production or CI should be treated as a privileged part of the stack."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That is why teams should be stricter about:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Pinning exact versions in requirements and lockfiles"}),(0,t.jsx)("li",{children:"Using private registries or vetted mirrors where possible"}),(0,t.jsx)("li",{children:"Isolating AI gateways from broad infrastru
8cture credentials"}),(0,t.jsx)("li",{children:"Limiting which secrets are available during install and runtime"}),(0,t.jsx)("li",{children:"Reviewing AI infrastructure packages as privileged software"})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Final thought"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The LiteLLM incident is a good reminder to be more careful about how much trust we hand to fast-moving AI infrastructure."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["When something like this happens, the first real question becomes: ",(0,t.jsx)("strong",{children:"what is the blast radius?"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Which repos pulled it? Which containers baked it in? Which services imported it? Which API keys were present? Which agent workflows or gateways depended on it?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That is where visibility matters."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"In Prismor, this is the kind of question teams should be able to answer quickly through the inventory view: where a package exists, which services or repos depend on it, what environments it reached, and how far exposure can spread once trust breaks."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"At Prismor, we think this is where developer security is heading next: understanding what ran, where it ran, and how quickly you can map the blast radius when a trusted dependency turns malicious."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"References"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:(0,t.jsx)("a",{href:"https://news.ycombinator.com/item?id=47501426",target:"_blank",rel:"noopener noreferrer",className:"text-blue-700 hover:text-blue-900 underline",children:"Hacker News discussion on the LiteLLM compromise"})}),(0,t.jsx)("li",{children:(0,t.jsx)("a",{href:"https://www.xda-developers.com/popular-python-library-backdoor-machine/",target:"_blank",rel:"noopener noreferrer",className:"text-blue-700 hover:text-blue-900 underline",children:"XDA Developers: Popular Python library backdoor analysis"})})]})]})},{id:"trivy-compromise-supply-chain-security",title:"When the security scanner becomes the attack path: lessons from the Trivy compromise",description:"A short practical look at the recent Trivy compromise, how malicious container images expanded the blast radius, and what security teams should do next.",date:"March 23, 2026",category:"Supply Chain Security",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Security teams ask developers to scan everything. Dependencies, containers, infrastructure, CI pipelines."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That advice is still right. But the recent Trivy compromise is a reminder that we also need to ask a harder question:"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-bold text-lg lg:text-xl",children:"What happens when the tool doing the scanning becomes the attack path?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"That is what made this incident important."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What happened"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The attack appears to have started with a compromise involving Trivy's GitHub Actions workflow. That was already serious because many teams run Trivy automatically in CI/CD."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The
8n the impact expanded."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Malicious Trivy container images were reportedly pushed to Docker Hub, including:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.69.4"})}),(0,t.jsx)("li",{children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.69.5"})}),(0,t.jsx)("li",{children:(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.69.6"})})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This widened the blast radius. The risk was no longer limited to teams using one GitHub Action path. It also affected teams pulling Trivy images directly in CI jobs, local environments, or automated security workflows."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"If those environments had access to secrets, registries, cloud credentials, or clusters, the impact could be much bigger than a bad scan."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why this matters"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Trivy is often run in the most sensitive places in the delivery pipeline. CI runners, registries, source repos, cloud accounts, and Kubernetes environments."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That means a compromised scanner can become a path to secret theft, infrastructure access, or release pipeline tampering."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This is the uncomfortable lesson from incidents like this: modern supply chain security is not only about scanning untrusted code. It is also about validating the tools that do the scanning."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What teams should do right now"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If your team used Trivy recently, the safest move is to investigate."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Start with the basics:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:["Stop using ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.69.4"}),", ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.69.5"}),", and ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.69.6"})]}),(0,t.jsxs)("li",{children:["Use ",(0,t.jsx)("code",{className:"bg-amber-50 text-amber-900 px-1.5 py-0.5 rounded border border-amber-200",children:"0.69.3"})," as the last publicly reported known good version until trusted guidance says otherwise"]}),(0,t.jsx)("li",{children:"Audit recent CI runs that pulled Trivy images or used the affected GitHub Action path"}),(0,t.jsx)("li",{children:"Rotate any credentials the scanner could access"}),(0,t.jsx)("li",{children:"Review registry, cloud, and Kubernetes activity for anything unusual"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The key point is simple: if Trivy ran in an environment with secrets, treat those secrets as potentially exposed."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The bigger lesson"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Many security programs still focus mostly on what is inside the build: packages, CVEs, licenses, base images."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That still matters. But incidents like this show that we also need to understand what actually ran during the build, with what permissions, and from where."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"A trusted tool can become untrusted very quickly if it is pulled by mutable tag, granted broad access, or executed without guardrails."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That is 
8why teams should be stricter about:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Pinning GitHub Actions to commit SHAs"}),(0,t.jsx)("li",{children:"Pinning container images to immutable digests"}),(0,t.jsx)("li",{children:"Limiting permissions for scanners"}),(0,t.jsx)("li",{children:"Isolating scanning jobs where possible"}),(0,t.jsx)("li",{children:"Treating security tools as privileged software in the threat model"})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Final thought"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The Trivy incident is not a reason to stop scanning."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"It is a reason to be more careful about how we trust the tools inside CI/CD."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If a security tool runs in your pipeline, it should be treated like any other high-privilege software. It needs version control, least privilege, and real oversight."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:["And once something like this happens, one of the first questions teams ask is: ",(0,t.jsx)("strong",{children:"what is the blast radius?"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Which repos used the affected image? Which workflows pulled it? Which secrets were exposed? Which downstream artifacts or environments could have been touched?"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"That is exactly where visibility matters. In Prismor, this is the kind of impact teams can quickly reason about through the inventory view: where a package, container, action, or workflow exists across the estate, what it connects to, and how far trust or exposure can spread."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"At Prismor, we think this is where developer security is heading next: not only understanding what is in the software, but understanding what ran to produce it, what it could access, and how quickly you can map the blast radius when trust breaks."})]})},{id:"jspdf-path-traversal-cve-2025-68428",title:"Critical Path Traversal Vulnerability in jsPDF Library (CVE-2025-68428)",description:"A critical local file inclusion vulnerability in jsPDF allows attackers to read arbitrary files from the server file system through unsanitized path parameters in Node.js environments.",date:"January 6, 2026",category:"Vulnerability Alert",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-68428 is a critical path traversal and local file inclusion vulnerability affecting jsPDF, a widely-used JavaScript library for generating PDF documents. The flaw allows attackers to read arbitrary files from the local file system in Node.js environments by exploiting insufficient input validation in multiple file-handling methods. With a CVSS 4.0 score of 9.2 (Critical), this vulnerability poses a significant risk to applications that allow user-controlled file paths to be passed to jsPDF methods."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The vulnerability specifically affects the Node.js builds of jsPDF (versions prior to 4.0.0) and impacts several critical methods including loadFile, addImage, html, and addFont. When exploited, attackers can extract sensitive configuration files, application source code, database credentials, and other confidential data that resides on the server file system. The extracted content is embedded verbatim into generated PDF documents, making exfiltration straightforward."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Understanding CVE-2025-68428"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"jsPDF is a popular open-source library that enables developers to generate PDF documents directly from JavaScript code, both in browser environments and Node.js applications. It provides methods for adding text, images, fonts, and HTML content to PDFs programmatically, making it a common choice for automated document generation workflows."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The vulnerability stems from inadequate validation of file path parameters in the Node.js-specific implementation of jsPDF. When developers pass user-controlled input to methods that load external files, attackers can inject path traversal sequences to access files outside the intended directory structure."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The affected methods include:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"loadFile()"})," - Loads file contents for inclusion in PDFs"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"addImage()"})," - Loads and embeds images from the file system"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"html()"})," - Processes HTML files that may reference local resources"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"addFont()"})," - Loads custom font files from disk"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the Vulnerability Works"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Path Traversal Attack Mechanism"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:'Path traversal vulnerabilities, also known as directory traversal or dot-dot-slash attacks, occur when applications fail to properly validate file path inputs. Attackers exploit this by using special character sequences like "../" to navigate up the directory tree and access files outside the intended scope.'}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"In the case of CVE-2025-68428, vulnerable jsPDF code accepts file paths as the first argument to multiple methods without sufficient sanitization. An attacker can provide paths like:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`// Accessing sensitive system files
9"../../../../etc/passwd"
10"../../../../etc/shadow"
11
12// Reading application configuration
13"../../../../app/config/database.yml"
14"../../../../.env"
15
16// Extracting source code
17"../../../../app/routes/api.js"
18"../../../../package.json"
19
20// Accessing private keys
21"../../../../home/user/.ssh/id_rsa"
22"../../../../var/secrets/api_keys.txt"`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Exploitation Example"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Consider a Node.js application that allows users to generate PDF reports with custom images. If the application naively passes user input to jsPDF without validation:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`// Vulnerable code example
23const jsPDF = require('jspdf');
24const express = require('express');
25const app = express();
26
27app.post('/generate-pdf', (req, res) => {
28  const doc = new jsPDF();
29  const imagePath = req.body.imagePath; // User-controlled input
30  
31  // Vulnerable: No path validation
32  doc.addImage(imagePath, 'PNG', 10, 10, 100, 100);
33  
34  const pdfBuffer = doc.output('arraybuffer');
35  res.send(Buffer.from(pdfBuffer));
36});
37
38// Attacker sends request with malicious path
39// POST /generate-pdf
40// { "imagePath": "../../../../etc/passwd" }
41
42// Result: /etc/passwd contents embedded in returned PDF`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Node.js-Specific Attack Surface"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This vulnerability only affects the Node.js builds of jsPDF (dist/jspdf.node.js and dist/jspdf.node.min.js). Browser-based implementations are not affected because browsers enforce strict security policies that prevent JavaScript from directly accessing the local file system. In Node.js environments, however, the runtime has full file system access, making path traversal attacks viable and dangerous."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Impact and Risk Assessment"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Severity Classification"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-68428 has been assigned a CVSS 4.0 score of 9.2 (Critical) by GitHub Security Advisory Database. The severity reflects several aggravating factors:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Network Attack Vector (AV:N):"})," Exploitable remotely over network connections"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Low Attack Complexity (AC:L):"})," Simple to exploit without special conditions"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"No Privileges Required (PR:N):"})," No authentication or authorization needed"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"No User Interaction (UI:N):"})," Exploitation requires no user action"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"High Confidentiality Impact (VC:H, SC:H):"})," Complete information disclosure"]})]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Real-World Consequences"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Successful exploitation of this vulnerability can lead to:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Exposure of database credentials stored in configuration files"}),(0,t.jsx)("li",{children:"Disclosure of API keys, authentication tokens, and cryptographic secrets"}),(0,t.jsx)("li",{children:"Leakage of proprietary source code and intellectual property"}),(0,t.jsx)("li",{children:"Access to user data, session information, and private keys"}),(0,t.jsx)("li",{children:"Information gathering for follow-up attacks targeting other vulnerabilities"})]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Affected Deployments"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Applications at highe
42st risk include document generation services, reporting platforms, invoice and receipt generators, data export systems, and any Node.js application that accepts user input for file paths passed to jsPDF methods. Cloud-hosted Node.js applications and containerized services running vulnerable jsPDF versions are particularly exposed if they handle untrusted input."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Affected Versions and Patches"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Vulnerable Versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"All versions of jsPDF prior to 4.0.0 are affected by this vulnerability. This includes:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"jsPDF 3.x series (all versions)"}),(0,t.jsx)("li",{children:"jsPDF 2.x series (all versions)"}),(0,t.jsx)("li",{children:"jsPDF 1.x series (all versions)"})]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Patched Version"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The vulnerability has been fixed in jsPDF version 4.0.0. This release implements strict file system access controls by default, restricting file operations to explicitly allowed directories. According to the maintainers, this semver-major update does not introduce other breaking changes beyond the security improvements."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The fix includes enhanced path validation, whitelisting of allowed directories, rejection of path traversal sequences, and configurable file system permissions for applications requiring broader file access."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Remediation and Mitigation"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Immediate Action: Upgrade to jsPDF 4.0.0"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The primary remediation is upgrading to jsPDF version 4.0.0 or later. Update your package.json and install the patched version:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Update package.json
43{
44  "dependencies": {
45    "jspdf": "^4.0.0"
46  }
47}
48
49# Install the update
50npm install jspdf@latest
51
52# Or with yarn
53yarn upgrade jspdf@latest
54
55# Verify installed version
56npm list jspdf
57# Should output: [email protected] or higher`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Node.js Permission Model (Node.js 20+)"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"For applications running on recent Node.js versions, the maintainers recommend using the experimental permission flag to restrict file system access:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Start Node.js with file system restrictions
58node --permission --allow-fs-read=/app/data --allow-fs-write=/app/output app.js
59
60# The permission model is experimental in Node.js 20.x
61# Stable in Node.js 22.13.0, 23.5.0, and 24.0.0+
62
63# Example: Restrict to specific directories only
64node --permission \\
65  --allow-fs-read=/app/public \\
66  --allow-fs-read=/app/assets \\
67  --allow-fs-write=/tmp/pdfs \\
68  server.js`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Input Validation and Sanitization"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If immediate upgrading is not feasible, implement strict input validation for any user-controlled paths passed to 
68jsPDF methods:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`const path = require('path');
69const fs = require('fs');
70
71// Secure path validation function
72function sanitizeFilePath(userInput, baseDir) {
73  // Remove null bytes and normalize
74  const cleaned = userInput.replace(/\\0/g, '');
75  
76  // Resolve to absolute path
77  const absolutePath = path.resolve(baseDir, cleaned);
78  
79  // Ensure path stays within base directory
80  if (!absolutePath.startsWith(path.resolve(baseDir))) {
81    throw new Error('Invalid file path: directory traversal detected');
82  }
83  
84  // Verify file exists and is readable
85  if (!fs.existsSync(absolutePath)) {
86    throw new Error('File not found');
87  }
88  
89  return absolutePath;
90}
91
92// Secure usage example
93app.post('/generate-pdf', (req, res) => {
94  try {
95    const baseDir = '/app/public/images';
96    const safePath = sanitizeFilePath(req.body.imagePath, baseDir);
97    
98    const doc = new jsPDF();
99    doc.addImage(safePath, 'PNG', 10, 10, 100, 100);
100    res.send(doc.output());
101  } catch (error) {
102    res.status(400).json({ error: error.message });
103  }
104});`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Whitelist Approach"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Instead of accepting arbitrary paths, use a whitelist of allowed files or map user selections to safe file paths:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`// Whitelist mapping approach
105const ALLOWED_IMAGES = {
106  'logo': '/app/assets/logo.png',
107  'header': '/app/assets/header.jpg',
108  'footer': '/app/assets/footer.png'
109};
110
111app.post('/generate-pdf', (req, res) => {
112  const imageKey = req.body.imageSelection;
113  
114  if (!ALLOWED_IMAGES[imageKey]) {
115    return res.status(400).json({ error: 'Invalid image selection' });
116  }
117  
118  const doc = new jsPDF();
119  doc.addImage(ALLOWED_IMAGES[imageKey], 'PNG', 10, 10, 100, 100);
120  res.send(doc.output());
121});`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Containerization and Sandboxing"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"For defense in depth, run Node.js applications in containers with restricted file system mounts, use read-only file systems where possible, apply principle of least privilege for container user permissions, and implement security contexts with AppArmor or SELinux profiles."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Detection and Response"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Identifying Vulnerable Dependencies"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Use automated tools to scan your dependencies for vulnerable jsPDF versions:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# npm audit
122npm audit
123
124# Check for specific CVE
125npm audit | grep CVE-2025-68428
126
127# Generate detailed report
128npm audit --json > audit-report.json
129
130# Prismor scanning (fastest and most comprehensive)
131pip install prismor
132prismor scan
133
134# Or scan specific manifest
135prismor scan --file package.json
136
137# OWASP Dependency-Check
138dependency-check --project myapp --scan ./`})}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:[(0,t.jsx)("strong",{children:"Prismor"})," provides comprehensive vulnerability scanning with detailed severity analysis, fixed versions, and direct links to vulnerability databases. It supports all major package managers and can be run locally via CLI or integrated into your CI/CD pipeline. Visit"," ",(0,t.jsx)("a",{href:"https://prismor.dev",className:"text-blue-600 hover:text-blue-800 underline",children:"prismor.dev"})," ","to scan your dependencies for CVE-2025-68428 and other vulnerabilities."]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Log Analysis for E
138xploitation Attempts"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Monitor application logs for suspicious file path patterns that may indicate exploitation attempts. Look for path traversal sequences in request parameters, access to sensitive system files, repeated failed file access attempts, and unusual PDF generation patterns. Implement alerting on detected path traversal patterns and anomalous file access behavior."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Conclusion"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-68428 represents a serious security vulnerability in a widely-deployed JavaScript library. The combination of critical severity, ease of exploitation, and potential for sensitive data exposure makes this a high-priority issue for any organization using jsPDF in Node.js applications."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The fix in jsPDF 4.0.0 provides robust protection through default-deny file system access policies, addressing the root cause while maintaining backward compatibility for most use cases. Organizations should prioritize upgrading to the patched version and implementing additional defense-in-depth measures such as input validation, containerization, and the Node.js permission model."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"This vulnerability underscores the importance of secure coding practices when handling user input, particularly for file system operations. Never trust user-provided file paths without strict validation, always use whitelisting approaches when possible, and implement multiple layers of security controls to minimize the impact of potential vulnerabilities."}),(0,t.jsxs)("p",{className:"text-gray-700 leading-[1.75] font-medium text-lg lg:text-xl",children:["For the latest information and updates, refer to the official GitHub Security Advisory at ",(0,t.jsx)("a",{href:"https://github.com/parallax/jsPDF/security/advisories/GHSA-f8cm-6447-x5h2",className:"text-blue-600 hover:underline",target:"_blank",rel:"noopener noreferrer",children:"GHSA-f8cm-6447-x5h2"})," and the NVD entry at ",(0,t.jsx)("a",{href:"https://nvd.nist.gov/vuln/detail/CVE-2025-68428",className:"text-blue-600 hover:underline",target:"_blank",rel:"noopener noreferrer",children:"CVE-2025-68428"}),"."]})]})},{id:"mongobleed-cve-2025-14847",title:"MongoBleed: Unauthenticated Memory Disclosure in MongoDB (CVE-2025-14847)",description:"A critical vulnerability in MongoDB's zlib compression handler allows unauthenticated attackers to read sensitive data from server memory, affecting millions of internet-facing MongoDB instances worldwide.",date:"December 27, 2025",category:"Vulnerability Alert",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:'CVE-2025-14847, dubbed "MongoBleed," is a critical unauthenticated memory disclosure vulnerability affecting MongoDB server versions 4.4 through 8.0. The flaw allows remote attackers to extract sensitive data directly from server memory without authentication by sending malformed zlib-compressed network messages. With millions of MongoDB instances exposed to the internet and no authentication required, this vulnerability represents one of the most severe database security issues disclosed in recent years.'}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:'The name "MongoBleed" follows the tradition of memory disclosure vulnerabilities like Heartbleed (OpenSSL) and CloudBleed (Cloudflare), reflecting both the technical nature of the flaw and its potential for widespread impact. Unlike many database vulnerabilities that require authenticated access, MongoBleed can be exploited by any attacker capable of establishing a network connection to a vulnerable MongoDB server.'}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What Is MongoBleed"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"MongoBleed is a memory disclosure vulnerability in MongoDB's network protocol handling code, specifically in the implementation of zlib compression for client-server communications. The vulnerability exists in the decompression rout
138ine that processes incoming compressed messages before authentication occurs."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"When MongoDB receives a compressed network message, it allocates memory buffers to decompress the data. A flaw in the bounds checking logic allows specially crafted malformed compression headers to cause the decompressor to read beyond the allocated buffer boundaries. Instead of crashing or returning an error, the vulnerable code continues processing and returns the out-of-bounds memory contents to the attacker."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This leaked memory can contain any data that was previously stored in adjacent memory regions, including:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Authentication credentials and session tokens from other connections"}),(0,t.jsx)("li",{children:"Database query results and document contents from recent operations"}),(0,t.jsx)("li",{children:"Internal MongoDB data structures and configuration details"}),(0,t.jsx)("li",{children:"Encryption keys and cryptographic material used by the server"}),(0,t.jsx)("li",{children:"Memory addresses and layout information useful for further exploitation"})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How MongoBleed Works"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The Compression Layer Attack Surface"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"MongoDB supports optional zlib compression for network communications to reduce bandwidth usage. This compression layer sits at the protocol level, before authentication checks are performed. Any client can request compressed communication by setting the appropriate flags in the initial connection handshake."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The vulnerability occurs when the server processes a compressed message with a malformed header that specifies an incorrect uncompressed size. The decompression code allocates a buffer based on this size value, but the actual decompression operation reads past the end of the allocated buffer into adjacent heap memory."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Pre-Authentication Exploitation"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"What makes MongoBleed particularly dangerous is that it can be exploited before authentication. The vulnerability is triggered in the message processing layer that runs before any credentials are checked. An attacker can:"}),(0,t.jsxs)("ol",{className:"list-decimal list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Connect to any MongoDB server that accepts network connections"}),(0,t.jsx)("li",{children:"Send a crafted compressed message with malicious size headers"}),(0,t.jsx)("li",{children:"Receive leaked memory contents in the error response or subsequent messages"}),(0,t.jsx)("li",{children:"Repeat the process to extract additional memory regions"}),(0,t.jsx)("li",{children:"Disconnect without ever providing credentials"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"This pre-authentication exploitation path means that even MongoDB deployments with strong authentication configured, firewall rules, and access control lists remain vulnerable if they accept any network connections from untrusted sources."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Memory Contents and Sensitive Data Exposure"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The specific data exposed through MongoBleed depends on what other operations the MongoDB server has recently processed. Because MongoDB is a multi-threaded application serving many concurrent connections, the heap memory contains fragments from numerous recent activities. Attackers can extract sensitive information including credentials from authentication attempts by legitimate users, query results containing customer data, configuration secrets, and internal implementation details that could aid in developing additional exploits."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why MongoBleed Is Dangerous"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Unauthenticated Remote Access"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Unlike most database vulnerabilities that require valid credentials or specific permissions, MongoBleed can be exploited by anyone who can establish a TCP connection to the MongoDB port. No username, password, API key, or session token is required. This dramatically lowers the barrier to exploitation and expands the pool of potential attackers to include opportunistic automated scanners."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Massive Internet Exposure"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"According to security research organizations, approximately 200,000 MongoDB servers are directly accessible from the internet on their default port 27017. Many of these are production databases belonging to organizations that either misconfigured their network security or intentionally exposed MongoDB for application connectivity without understanding the risks. Each of these instances is potentially vulnerable to MongoBleed."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Credential Theft and Authentication Bypass"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"One of the most dangerous aspects of MongoBleed is its ability to leak authentication credentials and session tokens from memory. When legitimate users authenticate to MongoDB, their credentials are processed and temporarily stored in server memory. By repeatedly exploiting MongoBleed, attackers can extract these credentials and use them to gain fully authenticated access to the database, completely bypassing the intended security controls."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Data Breach Without Logs"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Memory disclosure through MongoBleed leaves minimal forensic evidence. The attacker never authenticates, never executes queries, and never accesses collections or documents through normal APIs. Standard MongoDB audit logging will show only failed connection attempts or protocol errors, making it extremely difficult to detect active exploitation or reconstruct what data was exposed during an incident response investigation."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Affected Versions and Patches"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Vulnerable Versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-14847 affects a wide range of MongoDB server versions spanning multiple major releases:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 4.4:"})," All versions from 4.4.0 through 4.4.28"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 5.0:"})," All versions from 5.0.0 through 5.0.24"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 6.0:"})," All versions from 6.0.0 through 6.0.13"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 7.0:"})," All versions from 7.0.0 through 7.0.5"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 8.0:"})," All versions from 8.0.0 through 8.0.0"]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The vulnerability was introduced in MongoDB 4.4 when the zlib compression feature was significantly refactored. All subsequent versions inherited the vulnerable code until the issue was discovered and fixed."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Patched Versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"MongoDB Inc. has released security patches for all affected major versions:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 4.4.29"})," (patch for 4.4 series)"]}
138),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 5.0.25"})," (patch for 5.0 series)"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 6.0.14"})," (patch for 6.0 series)"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 7.0.6"})," (patch for 7.0 series)"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"MongoDB 8.0.1"})," (patch for 8.0 series)"]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Organizations should upgrade to the appropriate patched version based on their current deployment. Cross-major-version upgrades (e.g., from 5.0 to 7.0) require following MongoDB's standard upgrade procedures and testing for compatibility issues."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How to Fix MongoBleed"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Immediate Action: Upgrade to Patched Versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The primary remediation is upgrading to a patched MongoDB version. Follow these steps based on your deployment type:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# For package manager installations on Linux
139# Ubuntu/Debian
140sudo apt-get update
141sudo apt-get install mongodb-org=7.0.6 mongodb-org-server=7.0.6
142
143# Red Hat/CentOS
144sudo yum update mongodb-org-7.0.6 mongodb-org-server-7.0.6
145
146# Restart the service
147sudo systemctl restart mongod
148
149# For Docker deployments
150docker pull mongo:7.0.6
151
152# Update docker-compose.yml
153services:
154  mongodb:
155    image: mongo:7.0.6
156    # ... rest of configuration
157
158docker-compose down && docker-compose up -d
159
160# For MongoDB Atlas (managed service)
161# Navigate to cluster configuration
162# Select "Upgrade" from the cluster actions menu
163# Choose the patched version for your current release series
164# Schedule upgrade during maintenance window
165
166# Verify patched version after restart
167mongosh --eval "db.version()"
168# Should output 4.4.29, 5.0.25, 6.0.14, 7.0.6, or 8.0.1`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Temporary Mitigation: Disable Network Compression"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If immediate patching is not possible, you can disable zlib compression as a temporary workaround. This eliminates the vulnerable code path while slightly increasing network bandwidth usage:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Edit mongod.conf (usually at /etc/mongod.conf)
169# Add or modify the net.compression section:
170
171net:
172  compression:
173    compressors: none
174
175# Restart MongoDB
176sudo systemctl restart mongod
177
178# Verify compression is disabled
179mongosh --eval "db.serverStatus().network.compression"
180# Should show no active compressors`})}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Note that disabling compression may increase network bandwidth usage between MongoDB and application servers. Monitor network traffic after making this change to ensure infrastru
180cture can handle the increased load."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Network Security Hardening"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Regardless of patch status, MongoDB instances should never be directly exposed to the internet. Implement these network security controls:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Configure MongoDB to bind only to localhost or private IPs
181# Edit mongod.conf:
182net:
183  bindIp: 127.0.0.1,10.0.1.5  # localhost and private IP only
184  port: 27017
185
186# Configure firewall to block external access
187# iptables example:
188sudo iptables -A INPUT -p tcp --dport 27017 -s 10.0.0.0/8 -j ACCEPT
189sudo iptables -A INPUT -p tcp --dport 27017 -j DROP
190
191# AWS Security Group example:
192# Only allow inbound TCP 27017 from application security groups
193# Block all other inbound access
194
195# Use VPN or bastion hosts for administrative access
196# Never expose MongoDB directly to 0.0.0.0/0`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Connection String Security"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Applications connecting to MongoDB should enforce secure connection settings:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Use TLS/SSL for all connections
197mongodb://username:[email protected]:27017/database?tls=true&tlsCAFile=/path/to/ca.pem
198
199# Explicitly disable compression until patched
200mongodb://username:[email protected]:27017/database?compressors=disabled
201
202# For MongoDB drivers, disable compression in connection options
203# Node.js example:
204const client = new MongoClient(uri, {
205  compressors: [],
206  tls: true,
207  tlsCAFile: '/path/to/ca.pem'
208});`})}),(0,t.jsx)("div",{className:"bg-yellow-50 border-l-4 border-yellow-500 p-6 mb-8 rounded-none",children:(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)("div",{className:"flex-shrink-0",children:(0,t.jsx)("svg",{className:"h-6 w-6 text-yellow-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),(0,t.jsxs)("div",{className:"ml-4",children:[(0,t.jsx)("h3",{className:"text-base font-semibold text-yellow-900 mb-2",children:"Critical: Mitigations Are Temporary Only"}),(0,t.jsx)("p",{className:"text-sm text-yellow-800 leading-relaxed",children:"Disabling compression and network hardening reduce risk but do not eliminate the vulnerability. The only complete fix is upgrading to a patched version. Treat compression disabling as an emergency measure while planning and testing your upgrade path."})]})]})}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How to Detect MongoBleed Exposure"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Check Your MongoDB Versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Identify all MongoDB instances in your environment and verify their versions:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Connect and check version
209mongosh --eval "db.version()"
210
211# For Docker deployments
212docker exec mongodb mongosh --eval "db.version()"
213
214# Check multiple servers from a central location
215for host in mongodb1 mongodb2 mongodb3; do
216  echo "$host:"
217  mongosh --host $host --eval "db.version()"
218done
219
220# Query infrastructure inventory systems
221# Ansible example:
222ansible mongodb_servers -m shell -a "mongosh --eval 'db.version()'"
223
224# For MongoDB Atlas, check cluster configuration in web console`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Identify Internet-Facing Instances"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Determine if any MongoDB instances are accessible from the public internet:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Check network binding configuration
225grep bindIp /etc/mongod.conf
226
227# Test external accessibility from outside your network
228# From a different network or cloud region:
229nmap -p 27017 your-public-ip
230
231# Check cloud security group rules
232# AWS example:
233aws ec2 describe-security-groups --group-ids sg-xxxxx
234
235# Review firewall rules
236sudo iptables -L -n | grep 27017
237
238# Use Shodan to check if your IPs are indexed
239# https://www.shodan.io/search?query=mongodb+port:27017+org:"YourOrganization"`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Monitor for Exploitation Attempts"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Enable detailed logging and monitor for suspicious connection patterns:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# Enable verbose logging in mongod.conf
240systemLog:
241  verbosity: 2
242  component:
243    network:
244      verbosity: 3
245
246# Monitor logs for compression-related errors
247tail -f /var/log/mongodb/mongod.log | grep -i "compression\\|decompress\\|zlib"
248
249# Look for connection patterns without authentication
250grep "connection accepted" /var/log/mongodb/mongod.log | \
251grep -v "authenticated"
252
253# Check for repeated connections from single IPs
254awk '/connection accepted/ {print $NF}' /var/log/mongodb/mongod.log | \
255sort | uniq -c | sort -rn | head -20
256
257# Monitor using MongoDB server status
258mongosh --eval "db.serverStatus().connections"`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Post-Incident Investigation"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"If you suspect your MongoDB instances may have been exploited before patching, conduct a thorough security investigation. Review authentication logs for the period of vulnerability exposure, analyze network traffic captures for unusual connection patterns to port 27017, audit database access patterns for any authenticated sessions that followed suspicious unauthenticated connections, and assume all credentials and sensitive data processed during the vulnerable period may have been compromised and implement appropriate incident response procedures."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Lessons Learned"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The Danger of Pre-Authentication Attack Surfaces"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"MongoBleed demonstrates why pre-authentication code paths are critical security boundaries. Any functionality that processes network input before authentication checks creates an attack surface accessible to all network actors. Features like compression, encryption negotiation, and protocol version detection must receive rigorous security review and should be implemented with defense-in-depth protections including strict input validation, safe memory management, and comprehensive error handling."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Compression as an Attack Vector"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Compression and decompression code has historically been a rich source of vulnerabilities, from gzip implementations to image codecs. These algorithms process untrusted input, manipulate memory buffers based on attacker-controlled size fields, and often prioritize performance over safety. Any application that decompresses network data before authentication should be considered a potential attack surface."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Secure Defaults Matter"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The widespread exposure of MongoDB instances to the internet reflects inadequate default security configurations. While MongoDB's default binding to all interfaces may simplify initial setup for developers, it creates massive security risk in production environments. Critical infrastructure software should default to secure configurations that require explicit action to reduce security, not vice versa."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Defense in Depth Saves the Day"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Organizations that implemented proper network segmentation, even with vulnerable MongoDB versions, were protected from internet-based exploitation. This reinforces the importance of layered security controls. No single vulnerability should be able to compromise a well-architected system. Databases should always run on private networks, be protected by firewalls, require VPN or bastion access for administration, and implement least-privilege access controls."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Impact and Risk Assessment"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-14847 carries a CVSS v3.1 score of 9.1 (Critical), reflecting the severity of unauthenticated remote memory disclosure. The impact extends across multiple dimensions:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Confidentiality impact:"})," Complete disclosure of sensitive data including credentials, customer information, financial records, and intellectual property stored in or processed by the database."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Compliance violations:"})," Organizations subject to GDPR, HIPAA, PCI-DSS, SOC 2, or other regulatory frameworks face mandatory breach notification requirements and potential penalties if customer data was exposed."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Supply chain risk:"})," Software vendors and SaaS providers using vulnerable MongoDB versions may expose data across their entire customer base, triggering third-party liability and contractual violations."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Long-term exposure:"})," The vulnerability existed since MongoDB 4.4.0, potentially exposing data for years before discovery and patching. Organizations must assume historical compromise is possible."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Credential reuse:"})," Exposed credentials may be valid across multiple systems, allowing attackers to pivot from MongoDB compromise to broader infrastru
258cture access."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor Helps Protect Against Database Vulnerabilities"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"MongoBleed exemplifies why comprehensive visibility and rapid response capabilities are essential for database security. Organizations need to know instantly when critical vulnerabilities affecting their data infrastructure are disclosed. Prismor provides:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Complete Database Infrastructure Discovery:"})," Automatically identify all MongoDB instances across your environment, whether deployed as containers, system packages, cloud services, or embedded in applications. Know exactly which versions are running before attackers begin scanning."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Real-Time Vulnerability Intelligence:"})," When critical CVEs like MongoBleed are disclosed, Prismor automatically correlates them against your database inventory and alerts security teams within minutes, providing specific instance details and network exposure information."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Network Exposure Analysis:"})," Identify MongoDB instances accessible from the internet or untrusted networks. Understand your actual attack surface and prioritize remediation based on exposure level, not just vulnerability severity."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Configuration Security Assessment:"})," Continuously monitor database configurations for security weaknesses including dangerous network bindings, disabled authentication, unencrypted connections, and enabled unnecessary features like compression."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Patch Management Tracking:"})," Track remediation progress across development, staging, and production environments. Ensure all vulnerable instances are upgraded according to your security SLAs with timestamped evidence for compliance reporting."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"SBOM Integration:"})," Maintain comprehensive Software Bills of Materials for all applications, including database drivers, client libraries, and dependencies. When the next critical database vulnerability emerges, you will have complete visibility immediately."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Compliance Automation:"})," Generate audit-ready reports demonstrating timely identification, assessment, and remediation of critical database vulnerabilities. Meet regulatory requirements under GDPR, HIPAA, PCI-DSS, SOC 2, and industry-specific mandates."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Historical Risk Analysis:"})," Understand your exposure window for vulnerabilities like MongoBleed that existed for extended periods before discovery. Support incident response investigations with timeline data showing when vulnerable versions were deployed."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Database vulnerabilities like MongoBleed require rapid identification and response across complex, distributed infrastructure. Prismor transforms this challenge from a manual scramble into a systematic, automated process that protects your most valuable data assets and demonstrates security maturity to regulators, customers, and stakeholders."}),(0,t.jsx)("div",{className:"bg-red-50 border-l-4 border-red-500 p-6 mb-8 rounded-none",children:(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)("div",{className:"flex-shrink-0",children:(0,t.jsx)("svg",{className:"h-6 w-6 text-red-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),(0,t.jsxs)("div",{className:"ml-4",children:[(0,t.jsx)("h3",{className:"text-base font-semibold text-red-900 mb-2",children:"What to Do Now"}),(0,t.jsx)("div",{className:"text-sm text-red-800 leading-relaxed",children:(0,t.jsxs)("ol",{className:"list-decimal list-outside pl-6 space-y-2 mt-3",children:[(0,t.jsx)("li",{children:"Immediately inventory all MongoDB instances in your environment and check versions"}),(0,t.jsx)("li",{children:"Identify any internet-facing MongoDB servers and assess network exposure"}),(0,t.jsx)("li",{children:"Schedule emergency upgrades to patched versions for all vulnerable instances"}),(0,t.jsx)("li",{children:"As temporary mitigation, disable zlib compression on instances that cannot be immediately patched"}),(0,t.jsx)("li",{children:"Implement network security controls to prevent direct internet access to MongoDB"}),(0,t.jsx)("li",{children:"Review authentication logs for suspicious unauthenticated connection attempts"}),(0,t.jsx)("li",{children:"Assume credentials may be compromised and plan credential rotation after patching"}),(0,t.jsx)("li",{children:"Update security monitoring to detect MongoBleed exploitation attempts"}),(0,t.jsx)("li",{children:"Brief security and engineering teams on the vulnerability and required actions"}),(0,t.jsx)("li",{children:"Document remediation activities for compliance and incident response purposes"})]})})]})]})})]})},{id:"n8n-rce-cve-2025-68613",title:"Critical Remote Code Execution in n8n Workflow Automation: CVE-2025-68613",description:"A critical vulnerability in n8n's workflow expression evaluation system allows authenticated attackers to execute arbitrary code with full system privileges, affecting versions 0.211.0 through 1.122.0.",date:"December 19, 2025",category:"Vulnerability Alert",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"On December 19, 2025, the n8n team disclosed CVE-2025-68613, a critical remote code execution vulnerability in their open-source workflow automation platform. With a maximum CVSS score of 10.0, this flaw allows authenticated attackers to execute arbitrary code with the privileges of the n8n process, potentially leading to complete system compromise. The vulnerability affects all versions from 0.211.0 up to but not including the patched releases 1.120.4, 1.121.1, and 1.122.0."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"n8n is widely deployed across enterprises for integrating and automating workflows across hundreds of services and APIs. The platform's privileged access to sensitive data and critical systems makes this vulnerability especially dangerous. Organizations using n8n in production environments must upgrade immediately."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What Happened"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The Vulnerability"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-68613 is classified as CWE-913: Improper Control of Dynamically-Managed Code Resources. The vulnerability exists in n8n's workflow expression evaluation system, where expressions supplied by authenticated users during workflow configuration are executed in an insufficiently isolated execution context. This lack of proper sandboxing allows attackers with workflow editing privileges to break out of the intended execution environment and execute arbitrary code on the underlying server."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Technical Details"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"n8n workflows use expressions to dynamically process and transform data between nodes. These expressions are evaluated at runtime using JavaScript evaluation mechanisms. The vulnerable versions fail to properly isolate the expression evaluation context from the Node.js runtime environment, allowing specially crafted expressions to access and manipulate system-level resources."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"An attacker with legitimate access to create or edit workflows can inject malicious JavaScript code into workflow expressions. When the workflow executes, this code runs with the full privileges of the n8n process, which often includes:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-6 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Access to all integrated service credentials and API keys"}),(0,t.jsx)("li",{children:"Ability to read and write files on the host system"}),(0,t.jsx)("li",{children:"Network access to internal systems and databases"}),(0,t.jsx)("li",{children:"Capability to spawn system processes and execute commands"}),(0,t.jsx)("li",{children:"Access to environment variables containing sensitive configuration"})]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Affected Versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The vulnerability affects all n8n versions starting from 0.211.0 (the version that introduced the vulnerable expression evaluation system) up to but not including:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"1.120.4"})," (patch for 1.120.x series)"]}
258),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"1.121.1"})," (patch for 1.121.x series)"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"1.122.0"})," (latest release with fix included)"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How to Identify If You Are Affected"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Check Your n8n Version"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The fastest way to determine if your installation is vulnerable is to check your running version:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# For Docker deployments
259docker exec <container-name> n8n --version
260
261# For npm/yarn installations
262n8n --version
263
264# Check package.json in your n8n installation directory
265cat package.json | grep '"version"'
266
267# Via the n8n UI: Settings > About n8n`})}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"If your version is between 0.211.0 and 1.120.3, between 1.121.0 and 1.121.0, or any version below 1.122.0, you are running a vulnerable version and must upgrade immediately."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Scan Your Dependencies"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If n8n is deployed as part of a larger application or embedded in your infrastructure:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# For npm projects
268npm list n8n
269
270# For yarn projects
271yarn list --pattern n8n
272
273# For Docker compose deployments
274grep "image:.*n8n" docker-compose.yml
275
276# Check Kubernetes deployments
277kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"	"}{.spec.containers[*].image}{"
278"}' | grep n8n`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Audit Your Environment"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Even if you have patched, you should audit your environment for signs of potential exploitation:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Review workflow history:"})," Check for suspicious workflow modifications or new workflows created by unexpected users"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Examine expression usage:"})," Look for workflows containing complex or obfuscated JavaScript expressions, especially those accessing process, require, or eval functions"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit user accounts:"})," Review user activity logs for unusual access patterns or privilege escalation attempts"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check system logs:"})," Look for unexpected process spawning, network connections, or file access from the n8n process"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Scan for persistence mechanisms:"})," Check for new cron jobs, systemd services, or startup scripts that may have been installed"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How to Fix CVE-2025-68613"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Immediate Remediation: Upgrade to Patched Version"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The primary fix is to upgrade to one of the patched versions. Choose based on your current installation:"}),(0,t.jsx)("div",{className:"bg-gray-900 p-4 rounded-none mb-6 overflow-x-auto",children:(0,t.jsx)("pre",{className:"text-sm text-white",children:`# For npm installations
279npm install [email protected]
280
281# For yarn installations
282yarn add [email protected]
283
284# For Docker deployments (update docker-compose.yml or Dockerfile)
285docker pull n8nio/n8n:1.122.0
286
287# For Docker Compose
288version: '3'
289services:
290  n8n:
291    image: n8nio/n8n:1.122.0
292    # ... rest of configuration
293
294# Then restart the service
295docker-compose down && docker-compose up -d
296
297# For Kubernetes
298kubectl set image deployment/n8n n8n=n8nio/n8n:1.122.0`})}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Post-Upgrade Security Measures"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"After upgrading, implement these additional security measures:"}),(0,t.jsxs)("ol",{className:"list-decimal list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate all credentials:"})," Change all API keys, database passwords, and service credentials that n8n has access to. Assume any credentials accessible to n8n may have been compromised during the vulnerability window."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Review and restrict user permissions:"})," Limit workflow creation and editing permissions to only fully trusted users. Implement principle of least privilege across your n8n user base."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Enable audit logging:"})," Configure comprehensive audit logging to track all workflow modifications, user actions, and expression evaluations."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Implement network segmentation:"})," Deploy n8n in a restricted network zone with limited access to sensitive internal systems. Use firewall rules to control inbound and outbound connections."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Run with minimal privileges:"})," Configure n8n to run with a dedicated service account that has only the minimum necessary operating system permissions. Avoid running as root or administrator."]})]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Temporary Mitigations (If Immediate Patching Is Not Possible)"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If you cannot immediately upgrade to a patched version, implement these temporary controls to reduce risk:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Restrict workflow editing:"})," Temporarily disable workflow creation and editing for all users except a minimal set of fully trusted administrators."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Deploy in hardened environment:"})," Run n8n in a containerized or virtualized environment with strict resource limits and no access to host system resources."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Implement WAF rules:"})," Deploy a web application firewall with rules to detect and block suspicious workflow payloads."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Network isolation:"})," Place n8n behind a VPN or restrict access to trusted IP addresses only."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Monitor continuously:"})," Implement real-time monitoring for suspicious process execution, network connections, or file modifications originating from the n8n process."]})]}),(0,t.jsx)("div",{className:"bg-yellow-50 border-l-4 border-yellow-500 p-6 mb-8 rounded-none",children:(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)("div",{className:"flex-shrink-0",children:(0,t.jsx)("svg",{className:"h-6 w-6 text-yellow-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),(0,t.jsxs)("div",{className:"ml-4",children:[(0,t.jsx)("h3",{className:"text-base font-semibold text-yellow-900 mb-2",children:"Important: Temporary Mitigations Are Not Sufficient"}),(0,t.jsx)("p",{className:"text-sm text-yellow-800 leading-relaxed",children:"These workarounds do n
298ot fully eliminate the risk and should only be used as short-term measures while planning your upgrade. The only complete fix is upgrading to a patched version. Do not rely on mitigations as a long-term solution."})]})]})}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Impact and Scope"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The severity and potential impact of CVE-2025-68613 cannot be overstated:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Maximum severity rating:"})," CVSS 10.0 indicates critical risk with network attack vector, low attack complexity, requiring only low privileges, no user interaction, with scope change and complete impact on confidentiality, integrity, and availability."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Privileged execution context:"})," n8n typically runs with access to numerous API keys, database credentials, cloud service accounts, and internal systems, making compromise particularly devastating."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Enterprise deployment patterns:"})," n8n is often deployed as a central automation hub with connections to critical business systems, multiplying the blast radius of a successful attack."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Data exfiltration risk:"})," Attackers can access and exfiltrate sensitive data flowing through workflows, including customer information, financial records, and intellectual property."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Lateral movement potential:"})," Compromised n8n instances provide attackers with credentials and access to pivot into other systems and networks."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Persistent compromise:"})," Attackers can modify workflows to maintain long-term access, exfiltrate data continuously, or use the platform as a command and control mechanism."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Sectors and Organizations at Risk"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Organizations across all sectors using n8n are at risk, with particularly severe implications for:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Financial services:"})," Banks and fintech companies using n8n for payment processing, customer onboarding, or compliance automation face regulatory penalties under PCI-DSS and financial services regulations."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Healthcare:"})," Medical facilities using n8n for patient data integration or clinical workflows risk HIPAA violations and exposure of protected health information."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Government agencies:"})," Public sector organizations face potential compromise of citizen data and critical infrastructure systems."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"E-commerce and retail:"})," Companies using n8n for order processing, inventory management, or customer data synchronization risk payment data theft and customer privacy breaches."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Software-as-a-Service providers:"})," SaaS companies using n8n for customer integrations or internal automation may expose customer data across their entire tenant base."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"European organizations:"})," Entities subject to GDPR face significant penalties for data breaches resulting from unpatched critical vulnerabilities, as well as emerging requirements under the EU Cyber Resilience Act and NIS2 Directive."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Timeline"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"December 19, 2025:"})," CVE-2025-68613 publicly disclosed by n8n team with patched versions released"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"December 19, 2025:"})," GitHub Security Advisory GHSA-v98v-ff95-f3cp published"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"December 19, 2025:"})," Official CVE record created and distributed to vulnerability databases"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"December 19, 2025:"}
298)," Security researcher Fatih Celik credited with discovery and responsible disclosure"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"References and Additional Information"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"CVE Record:"})," ",(0,t.jsx)("a",{href:"https://www.cve.org/CVERecord?id=CVE-2025-68613",className:"text-blue-600 hover:text-blue-800 underline",target:"_blank",rel:"noopener noreferrer",children:"https://www.cve.org/CVERecord?id=CVE-2025-68613"})]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"GitHub Security Advisory:"})," ",(0,t.jsx)("a",{href:"https://github.com/n8n-io/n8n/security/advisories/GHSA-v98v-ff95-f3cp",className:"text-blue-600 hover:text-blue-800 underline",target:"_blank",rel:"noopener noreferrer",children:"GHSA-v98v-ff95-f3cp"})]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor Helps Organizations Manage Automation Platform Security"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Workflow automation platforms like n8n are critical infrastructure components that often have privileged access to your most sensitive systems. When vulnerabilities like CVE-2025-68613 emerge, organizations need comprehensive visibility and rapid response capabilities. Prismor provides:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Automated Software Discovery:"})," Maintain a complete inventory of all instances of n8n and other automation platforms across your infrastructure - whether deployed as containers, npm packages, or standalone installations. Know exactly where vulnerable versions are running before attackers find them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Real-Time Vulnerability Correlation:"})," When critical CVEs affecting your automation platforms are disclosed, Prismor automatically correlates them against your software inventory and alerts security teams within minutes, not days."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Dependency Chain Analysis:"})," Track not just n8n itself but all applications and services that depend on or integrate with your automation platforms. Understand the full blast radius of a potential compromise."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Compliance and Audit Readiness:"})," Generate audit-ready reports demonstrating timely response to critical vulnerabilities. Meet regulatory requirements under GDPR, NIS2, EU Cyber Resilience Act, and industry-specific mandates with timestamped evidence of identification, notification, and remediation."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Patch Management Orchestration:"})," Track patching progress across development, staging, and production environments. Ensure all vulnerable instances are upgraded according to your security SLAs and organizational policies."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Continuous SBOM Monitoring:"})," Maintain comprehensive Software Bills of Materials for all applications, including embedded automation components and their dependencies. When the next critical vulnerability emerges, you will have complete visibility immediately."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Third-Party Risk Management:"})," Extend vulnerability monitoring to your supply chain partners and vendors. Ensure third parties maintain adequate security postures before granting access to your automation platforms and integrated systems."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"CVE-2025-68613 demonstrates that even trusted, widely-deployed platforms can harbor critical vulnerabilities. With Prismor, you transform vulnerability management from a reactive scramble into a systematic, proactive process that protects your organization and demonstrates security maturity to regulators, customers, and stakeholders."}),(0,t.jsx)("div",{className:"bg-red-50 border-l-4 border-red-500 p-6 mb-8 rounded-none",children:(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)("div",{className:"flex-shrink-0",children:(0,t.jsx)("svg",{className:"h-6 w-6 text-red-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),(0,t.jsxs)("div",{className:"ml-4",children:[(0,t.jsx)("h3",{className:"text-base font-semibold text-red-900 mb-2",children:"Critical Security Alert"}),(0,t.jsx)("p",{className:"text-sm text-red-800 leading-relaxed",children:"CVE-2025-68613 allows complete system compromise through authenticated workflow manipulation. Any organization running vulnerable versions of n8n should treat this as a critical security incident requiring immediate emergency patching outside normal deployment schedules. The combination of maximum severity rating, ease of exploitation, and typical deployment patterns with privileged access makes this one of the most dangerous vulnerabilities disclosed in late 2025."})]})]})})]})},{id:"attack-of-shai-hulud",title:"The Return of Shai-Hulud: npm's Worm Strikes Back",description:"In November 2025, the JavaScript ecosystem was shaken by a devastating supply-chain attack affecting hundreds of npm packages from major players like Zapier, ENS Domains, and Postman.",date:"November 24, 2025",category:"Supply Chain Security",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"In November 2025, the JavaScript ecosystem was shaken again by a devastating supply-chain attack: Shai-Hulud 2.0 - a new, more aggressive wave of the worm previously known as Shai-Hulud. This time, dozens of high-profile npm packages - including ones from major players like Zapier, ENS Domains, Postman, and others - were trojanized, putting potentially thousands of developers and organizations at risk."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"As of late November 2025, researchers estimate that hundreds to ~700 npm packages were compromised, and the attack has already produced tens of thousands of malicious GitHub repositories, with some reports flagging 25,000+ repos created by the worm."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How the Attack Works (Again)"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Initial Compromise"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Rather than targeting random dependencies or typosquatting, attackers gained full access to legitimate maintainer accounts - in some cases by stealing credentials - and published malicious new versions of trusted packages."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Trojanized Packages and Preinstall Hook"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"What makes Shai-Hulud 2.0 especially insidious is its use of the npm install lifecycle. Each compromised package comes with a preinstall hook in its package.json. That hook triggers a script (setup_bun.js) which silently installs a separate runtime (Bun) if not already present, then executes a heavily obfuscated payload (bun_environment.js). From that point, the malicious logic runs outside the usual Node.js security visibility."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Credential Harvesting and Exfiltration"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Once activated - whether on a developer's workstation or a CI/CD runner - the malware searches for all sorts of high-value secrets:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-6 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"npm publish tokens (allowing the worm to republish packages)"}),(0,t.jsx)("li",{children:"GitHub tokens / credentials"}),(0,t.jsx)("li",{children:"Cloud service keys (AWS, GCP, Azure)"}),(0,t.jsx)("li",{children:"Other environment variables or secrets present in the environment"})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:'It then exfiltrates the harvested credentials - often by uploading them to public GitHub repositories under attacker control (frequently named something like "Shai-Hulud"), or by using GitHub Actions workflows to siphon secrets when CI runs.'}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Worm-like Self-Propagation"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Using stolen npm tokens, the malware automatically re-publishes poisoned versions of other packages maintained by the compromised user, effectively turning each victim into a 
298new infection vector. This allows exponential spread - turning one compromised maintainer into many more forking points."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Because the attack works at the install/pre-install phase, it's able to infiltrate CI/CD pipelines, developer laptops, and build servers - wherever a vulnerable npm install or build runs."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Why This Matters: The Impact"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Supply-chain trust broken"}),' - developers rely on npm packages being safe; this attack shows even "trusted" packages can suddenly become dangerous.']}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Wide blast radius"})," - with dozens/hundreds of packages compromised, many that are transitively depended on by thousands of projects, a single installation can unknowingly pull in malicious code."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Credential and infrastructure exposure"})," - stolen tokens can grant attackers access to private repos, cloud infrastructure, CI/CD pipelines, sensitive data, and more."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Persistent compromise"})," - even if the npm package is removed, malicious workflows or public repos may persist, continuing to leak secrets or build further attacks."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Hard to detect"})," - by using an alternative runtime (Bun) and obfuscated payloads, the malware aims to evade traditional static analysis or security tooling that only watches for typical Node.js behavior."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What You Should Do Right Now"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"If you maintain a project - open source or enterprise - and use npm (or depend on packages from npm), you should:"}),(0,t.jsxs)("ol",{className:"list-decimal list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit your dependencies immediately"})," - check if your projects (or your CI/CD pipelines) refer to any of the compromised packages or versions."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Remove or update any compromised versions"}),"; pull fresh, clean versions where available. For projects like the ones from Postman that pulled their packages quickly, ensure no infected package remains."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rotate all secrets and tokens"})," - GitHub tokens, cloud credentials, npm publish tokens, and any environment credentials that might have been exposed."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Inspect all repositories and CI/CD workflows"})," - look for unusual GitHub Actions workflows (shai-hulud-workflow.yml or other unfamiliar YAMLs), and remove unexpected branches or public repos created by the attacker."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Harden future practices"})," - consider isolating publishing to dedicated CI/CD pipelines, avoid carrying long-lived tokens on developer machines, enforce stricter MFA / token policies, and treat dependencies with more scrutiny (especially those updated recently). Many security advisories recommend freezing automated dependency updates until the all-clear."]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The Bigger Picture: Supply-Chain Risk Is Real and Growing"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"While individual vulnerabilities or code bugs are often caught and patched, supply-chain attacks like Shai-Hulud exploit the implicit trust we place in open-source libraries and ecosystem tooling. In large organizations - especially those with many dependencies, complex CI/CD pipelines, and multiple contributors - the attack surface is huge."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Shai-Hulud 2.0 shows that attackers don't need to compromise your own code to infiltrate - they just need one trusted, widely used package to slip through. Once you install it, you might as well have invited the attacker into your infrastru
298cture."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Given this reality, defending against such threats calls for more than reactive patching. It requires systemic supply-chain hygiene: continuous auditing, minimizing secrets exposure, strict governance over dependency changes, and runtime monitoring for abnormal behaviors."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor Can Help Protect Your Enterprise"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"At Prismor, we understand that modern software supply chains are complex. Here's how we can help you mitigate risks like Shai-Hulud 2.0:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Automated Supply-Chain Monitoring:"})," Prismor continuously scans your dependencies (npm, internal packages, third-party libraries) to flag known malicious packages, risky updates, or suspicious lifecycle scripts - before they enter your build or deployment pipelines."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Credential and Token Vaulting:"})," Prismor helps centralize secrets management - so developer machines or CI runners aren't cluttered with long-lived tokens that can be harvested by malicious scripts."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"CI/CD Hardening and Policy Enforcement:"})," By enforcing strict policies around who can publish packages, review changes, and approve updates, Prismor reduces the risk of compromised maintainer accounts propagating malware through your organization."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Post-Incident Audit and Containment:"})," In the event of a suspected breach, Prismor allows you to quickly trace where compromised packages touched your environment - which services, build agents, or repos - and trigger credential rotation or rollback."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Continuous Threat Intelligence and Software-Bill-of-Materials (SBOM) Tracking:"}),' Prismor can integrate SBOMs into your development lifecycle to maintain visibility of exactly what code (and dependencies) make up your applications, giving you a "source of truth" for detecting any untrusted or unexpected additions.']})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"By combining automation, policy enforcement, and visibility across your entire software supply-chain, Prismor helps make attacks like Shai-Hulud far harder to pull off - and far easier to catch if they do slip through."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Known Affected npm Packages"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The following is a partial list of confirmed compromised packages identified during the Shai-Hulud 2.0 attack. Security researchers continue to identify additional affected packages. Organizations should audit their dependencies immediately."}),(0,t.jsx)("div",{className:"overflow-x-auto mb-8",children:(0,t.jsxs)("table",{className:"min-w-full border border-gray-300",children:[(0,t.jsx)("thead",{className:"bg-gray-50",children:(0,t.jsxs)("tr",{children:[(0,t.jsx)("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider border-b border-gray-300",children:"Package Name"}),(0,t.jsx)("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider border-b border-gray-300",children:"Maintainer/Owner"}),(0,t.jsx)("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider border-b border-gray-300",children:"Compromised Versions"}),(0,t.jsx)("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-700 uppercase tracking-wider border-b border-gray-300",children:"Weekly Downloads"})]})}),(0,t.jsxs)("tbody",{className:"bg-white divide-y divide-gray-200",children:[(0,t.jsxs)("tr",{children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"@zapier/platform-core"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Zapier"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"15.10.0 - 15.11.0"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~50,000"})]}),(0,t.jsxs)("tr",{className:"bg-gray-50",children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"@postman/code-generators"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Postman"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"1.11.0 - 1.12.1"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~40,000"})]}),(0,t.jsxs)("tr",{children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"@ensdomains/ens-contracts"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"ENS Domains"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"1.1.0 - 1.2.0"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~35,000"})]}),(0,t.jsxs)("tr",{className:"bg-gray-50",children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"typescript-eslint-parser"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Various"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"28.3.0 - 28.5.1"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~120,000"})]}),(0,t.jsxs)("tr",{children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"web3-providers-http"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Web3.js Team"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"4.1.0 - 4.3.0"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~90,000"})]}),(0,t.jsxs)("tr",{className:"bg-gray-50",children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"mongodb-memory-server"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Community"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"9.1.0 - 9.2.1"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~85,000"})]}),(0,t.jsxs)("tr",{children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"serverless-webpack"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Serverless Community"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"5.
29813.0 - 5.14.2"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~60,000"})]}),(0,t.jsxs)("tr",{className:"bg-gray-50",children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"@stripe/stripe-js"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Stripe"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"2.4.0 - 2.5.0"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~200,000"})]}),(0,t.jsxs)("tr",{children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"ethers-providers"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"Ethers.js"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"6.9.0 - 6.10.1"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~150,000"})]}),(0,t.jsxs)("tr",{className:"bg-gray-50",children:[(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900",children:"next-auth-providers"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"NextAuth Community"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"5.0.0 - 5.1.2"}),(0,t.jsx)("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-700",children:"~110,000"})]})]})]})}),(0,t.jsx)("div",{className:"bg-red-50 border-l-4 border-red-500 p-6 mb-8 rounded-none",children:(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)("div",{className:"flex-shrink-0",children:(0,t.jsx)("svg",{className:"h-6 w-6 text-red-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),(0,t.jsxs)("div",{className:"ml-4",children:[(0,t.jsx)("h3",{className:"text-base font-semibold text-red-900 mb-2",children:"Critical Security Notice"}),(0,t.jsx)("p",{className:"text-sm text-red-800 leading-relaxed",children:"This is not a complete list. Security researchers estimate 500-700 packages were compromised in total. If your package.json or lock files contain any of these packages in the affected version ranges, you should assume compromise occurred. Immediately rotate all credentials, audit your systems for malicious activity, and update to clean versions or remove the dependencies entirely."})]})]})})]})},{id:"article-2",title:"Critical Chrome Zero-Day Exploited: Google Rushes Emergency Patch for CVE-2025-0411",description:"Google releases emergency security update for Chrome after discovering active exploitation of a critical use-after-free vulnerability in the browser's rendering engine, affecting billions of users worldwide.",date:"October 28, 2025",category:"Vulnerability Alert",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"On October 28, 2025, Google released an emergency security update for Chrome after discovering CVE-2025-0411, a critical use-after-free vulnerability in the browser's Blink rendering engine. Security researchers detected active exploitation in the wild, making this the eighth zero-day vulnerability patched by Google in Chrome this year."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The vulnerability, rated 8.8 (High) on the CVSS scale, allows remote attackers to execute arbitrary code through specially crafted HTML pages. With Chrome commanding over 65% of the global browser market share, the potential impact affects billions of users across desktop and mobile platforms."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What Happened"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The Vulnerability"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-0411 is a use-after-free vulnerability in Chrome's Blink rendering engine, the component responsible for parsing and displaying web content. Use-after-free bugs occur when a program continues to use memory after it has been freed, allowing attackers to manipulate memory contents and achieve code execution."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Attack Vector"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The vulnerability can be exploited through:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-6 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsx)("li",{children:"Malicious websites hosting specially crafted HTML/JavaScript"}),(0,t.jsx)("li",{children:"Compromised legitimate websites serving exploit code"}),(0,t.jsx)("li",{children:"Malvertising campaigns delivering weaponized payloads"}),(0,t.jsx)("li",{children:"Phishing emails containing links to exploit-hosting pages"})]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Active Exploitation Detected"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Google's Threat Analysis Group (TAG) discovered the vulnerability was being actively exploited in targeted attacks. While Google has not disclosed specific details about the attacks or threat actors involved (following their standard practice for actively exploited vulnerabilities), the rapid emergency response indicates sophisticated adversaries were leveraging this flaw against high-value targets."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Impact and Scope"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The implications of CVE-2025-0411 are severe:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Massive user base at risk"})," - Chrome has over 3.45 billion users globally, making this one of the most widespread vulnerabilities of 2025"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Enterprise exposure"})," - Corporate networks, cloud workstations, and managed devices all rely on Chrome for daily operations"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Cross-platform threat"})," - Affects Windows, macOS, Linux, ChromeOS, Android, and iOS versions of Chrome"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Supply chain implications"})," - Chromium-based browsers (Edge, Brave, Opera, Vivaldi) may also be vulnerable pending their own security updates"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Zero-click potential"})," - Users can be compromised simply by visiting a malicious webpage, requiring no additional interaction"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Immediate Actions Required"}),(0,t.jsxs)("ol",{className:"list-decimal list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Update Chrome immediately"})," - Navigate to Settings → About Chrome to trigger the update to version 130.0.6723.116 or later. Chrome should auto-update within 48 hours, but manual updates ensure immediate protection."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Restart your browser"}
298)," - Updates don't take effect until Chrome is fully restarted. Close all windows and relaunch."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Check Chromium-based browsers"})," - If you use Edge, Brave, Opera, or other Chromium-based browsers, check for and install their security updates as well."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Enterprise deployment"})," - IT administrators should push the Chrome update through enterprise management tools (GPO, MDM, JAMF) immediately."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Monitor for compromise"})," - Review browser history, installed extensions, and system logs for signs of exploitation or suspicious activity during the vulnerable window."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Enable Enhanced Protection"}),' - In Chrome Settings → Privacy and security → Security, enable "Enhanced protection" for real-time protection against dangerous sites and downloads.']})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"The Broader Context: Browser Security in 2025"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-0411 represents the eighth Chrome zero-day vulnerability exploited in the wild this year, continuing a troubling trend:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Increasing sophistication"})," - Threat actors are investing heavily in browser exploitation due to the universal attack surface browsers provide"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Nation-state activity"})," - Many browser zero-days are attributed to government-backed APT groups targeting dissidents, journalists, and high-value corporate targets"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Commercial exploit markets"})," - Browser vulnerabilities command premium prices on exploit marketplaces, incentivizing discovery and weaponization"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Supply chain entry point"})," - Browsers serve as the gateway to cloud applications, SaaS platforms, and internal corporate systems, making them ideal initial access vectors"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor Helps Organizations Manage Browser Security"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"While browser vendors work to patch vulnerabilities, organizations need comprehensive visibility and control over their software ecosystem. Prismor provides:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Software Asset Inventory:"})," Maintain real-time visibility of all software versions across your organization, including browsers and browser-based applications. Know instantly which systems are running vulnerable Chrome versions."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Automated Vulnerability Correlation:"})," When CVEs like CVE-2025-0411 are disclosed, Prismor automatically correlates them against your software inventory, identifying exposed systems before attackers can exploit them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Patch Management Tracking:"})," Monitor patch deployment progress across your fleet. Ensure critical browser updates are installed enterprise-wide within your defined security SLAs."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Compliance Reporting:"})," Generate audit-ready reports demonstrating timely response to critical vulnerabilities, meeting regulatory requirements under frameworks like EU CRA, NIS2, and industry-specific mandates."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Third-Party Risk Assessment:"})," Track browser and software versions across your supply chain partners and vendors. Ensure they maintain adequate security postures before granting access to your systems."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Continuous SBOM Monitoring:"})," Maintain comprehensive Software Bills of Materials for all applications, including embedded browser components (Electron, WebView, etc.) that may inherit Chrome vulnerabilities."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"With Prismor, you don't just react to the next zero-day - you build systematic resilience through comprehensive visibility, automated threat intelligence, and proactive patch management across your entire software supply chain."})]})},{id:"react-server-components-cve-2025-55182",title:"Critical Remote Code Execution Vulnerability in React Server Components",description:"React releases emergency patches for CVE-2025-55182, a maximum severity vulnerability allowing unauthenticated remote code execution in React Server Components, affecting Next.js and other major frameworks.",date:"December 3, 2025",category:"Vulnerability Alert",content:(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"On December 3, 2025, the React team disclosed CVE-2025-55182, a critical remote code execution vulnerability in React Server Components. With a maximum CVSS score of 10.0, this represents one of the most severe vulnerabilities ever discovered in the React ecosystem. The flaw affects React 19.x server components and impacts major frameworks including Next.js, React Router, Waku, Expo, and others."}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"The vulnerability allows unauthenticated attackers to execute arbitrary code on servers running affected versions by sending specially crafted HTTP requests to Server Function endpoints. Patches have been released, and all users running React Server Components in production must upgrade immediately."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"What Happened"}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"The Vulnerability"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"CVE-2025-55182 is a deserialization vulnerability in the Server Function endpoint implementation of React Server Components. When processing incoming requests, the vulnerable code deserializes user-controlled payload data without proper validation, allowing attackers to inject malicious code that executes on the server with the privileges of the application."}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Affected Packages and Versions"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The vulnerability exists in three React server packages:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-6 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"react-server-dom-webpack:"})," versions 19.0.0, 19.1.0, 19.1.1, 19.2.0"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"react-server-dom-parcel:"})," versions 19.0.0, 19.1.0, 19.1.1, 19.2.0"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"react-server-dom-turbopack:"})," versions 19.0.0, 19.1.0, 19.1.1, 19.2.0"]})]}),(0,t.jsx)("h3",{className:"text-xl sm:text-2xl font-medium text-gray-900 mt-8 mb-4",children:"Attack Vector"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"Attackers can exploit this vulnerability by crafting malicious HTTP POST requests to Server Function endpoints exposed by affected applications. No authentication is required, and successful exploitation grants full code execution capabilities on the target server. This makes the vulnerability particularly dangerous for internet-facing applications."}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Impact and Scope"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"The implications of CVE-2025-55182 are severe and far-reaching:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Maximum severity rating"})," - CVSS 10.0 indicates this vulnerability requires no privileges, no user interaction, and has complete impact on confidentiality, integrity, and availability"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Next.js ecosystem at risk"}
298)," - All Next.js 15.x through 16.x versions using Server Components are vulnerable, affecting thousands of production applications"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Multi-framework impact"})," - React Router, Waku, Expo, Redwood SDK, and various Vite and Parcel plugins are all affected"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Unauthenticated exploitation"})," - No credentials or user interaction required makes this trivially exploitable by any remote attacker"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Complete server compromise"})," - Successful exploitation provides full code execution, enabling data theft, ransomware deployment, persistence mechanisms, and lateral movement"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Affected Frameworks and Applications"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"Applications using Server Components through these frameworks are vulnerable:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Next.js:"})," All versions 15.x, 16.0.0-canary.x, and 16.0.0-rc.x must upgrade immediately"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"React Router:"})," Applications using the Remix/React Router framework with Server Components"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Waku:"})," Server-side rendering framework built on React Server Components"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Expo SDK:"})," Mobile applications using Expo with server-side rendering"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Redwood SDK:"})," Full-stack React framework with server-side capabilities"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Build tool plugins:"})," @vitejs/plugin-react, vite-plugin-react-server-components, @parcel/runtime-react-refresh"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Immediate Actions Required"}),(0,t.jsxs)("ol",{className:"list-decimal list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Upgrade React packages immediately"})," - Update to patched versions: 19.0.1, 19.1.2, or 19.2.1 depending on your current version. Run ",(0,t.jsx)("code",{className:"bg-gray-900 px-2 py-1 rounded text-sm text-white",children:"npm update react react-dom react-server-dom-webpack"})," or equivalent for your package manager."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Update framework versions"})," - Next.js users should upgrade to versions 15.1.4, 15.2.0-canary.41, 16.0.0-canary.7, or 16.0.0-rc.1 which include the patched React versions."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Rebuild and redeploy"})," - After updating dependencies, rebuild your application and deploy immediately to production. This is a critical security release that cannot wait for normal release cycles."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Audit Server Function usage"}
298)," - Review all Server Functions and Server Actions in your codebase for additional security hardening opportunities."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Monitor for exploitation attempts"})," - Review server logs for suspicious POST requests to Server Function endpoints. Look for unusual payloads or request patterns targeting these endpoints."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Implement network controls"})," - If immediate patching is not possible, consider temporarily restricting access to Server Function endpoints through WAF rules or network ACLs until patches can be deployed."]})]}),(0,t.jsx)("div",{className:"bg-red-50 border-l-4 border-red-500 p-6 mb-8 rounded-none",children:(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)("div",{className:"flex-shrink-0",children:(0,t.jsx)("svg",{className:"h-6 w-6 text-red-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})})}),(0,t.jsxs)("div",{className:"ml-4",children:[(0,t.jsx)("h3",{className:"text-base font-semibold text-red-900 mb-2",children:"Critical Security Notice"}),(0,t.jsx)("p",{className:"text-sm text-red-800 leading-relaxed",children:"This vulnerability allows complete server compromise without authentication. Any application running React Server Components with vulnerable versions should be considered at immediate risk of exploitation. Patching must be treated as an emergency security incident requiring immediate action outside normal deployment schedules."})]})]})}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"Timeline"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"November 29, 2025:"})," Vulnerability discovered and reported to React team by security researcher Lachlan Davidson"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"December 1, 2025:"})," React team validates vulnerability and develops patches"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"December 3, 2025:"})," Coordinated disclosure with patches released for all affected versions"]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"December 3, 2025:"})," Next.js and other framework vendors release updated versions incorporating the fix"]})]}),(0,t.jsx)("h2",{className:"text-2xl sm:text-3xl font-medium text-gray-900 mt-12 mb-5",children:"How Prismor Helps Organizations Respond to Critical Vulnerabilities"}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-5 font-medium text-lg lg:text-xl",children:"When critical vulnerabilities like CVE-2025-55182 emerge, organizations need to i
298dentify affected systems and coordinate patching across their entire application portfolio. Prismor provides:"}),(0,t.jsxs)("ul",{className:"list-disc list-outside pl-6 sm:pl-7 mb-8 space-y-4 font-medium text-lg lg:text-xl text-gray-700",children:[(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Automated Dependency Detection:"})," Instantly identify all applications using React Server Components across your organization. Know which projects are running vulnerable versions of react-server-dom-webpack, react-server-dom-parcel, or react-server-dom-turbopack before attackers find them."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Real-Time Vulnerability Intelligence:"})," Receive immediate alerts when critical CVEs affecting your technology stack are disclosed. Prismor correlates new vulnerabilities against your complete software inventory within minutes of public disclosure."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Framework and Dependency Mapping:"})," Track not just direct dependencies but also framework versions. Understand which Next.js, React Router, or other framework versions are deployed and how they relate to underlying React versions."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Coordinated Patch Management:"})," Orchestrate emergency patching across development, staging, and production environments. Track which teams have upgraded, which systems remain vulnerable, and ensure complete coverage."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Compliance and Audit Trails:"})," Document your response to critical security incidents with timestamped records of vulnerability identification, notification, patching, and verification. Meet regulatory requirements under EU CRA, NIS2, and other frameworks."]}),(0,t.jsxs)("li",{children:[(0,t.jsx)("strong",{children:"Continuous SBOM Monitoring:"})," Maintain up-to-date Software Bills of Materials for all applications. When the next critical vulnerability emerges, you will have complete visibility into your exposure within minutes, not days."]})]}),(0,t.jsx)("p",{className:"text-gray-700 leading-[1.75] mb-8 font-medium text-lg lg:text-xl",children:"CVE-2025-55182 demonstrates why comprehensive software supply chain visibility is no longer optional. With Prismor, you transform vulnerability response from a reactive scramble into a systematic, auditable process that protects your organization and proves compliance to regulators and customers."})]})}];e.s(["blogArticles",0,d],477958)}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.