CVE-2026-26030 in Microsoft Semantic Kernel is the third AI agent framework to ship the same architectural fault in fourteen months. This article skips the step-by-step attack walkthrough — the advisory covers that — and focuses on the design failure that made exploitation possible, what it means for your threat model, and what a system designed against this pattern looks like.
Executive Summary
CVE-2026-26030 is a remote code execution (RCE) vulnerability in the Microsoft Semantic Kernel Python Software Development Kit (SDK), affecting all versions prior to 1.39.4. The root cause is a design failure: InMemoryVectorStore’s filter interface accepted caller-supplied field selector strings and resolved them through Python’s own attribute access mechanism — with no isolation boundary between “query parameter” and “Python runtime object.” An attacker with any low-privilege authenticated account can submit a filter expression containing Python dunder attributes, traverse the object model to reach the import and builtins infrastructure, and execute arbitrary code as the agent process OS user, gaining access to all loaded API keys, credentials, agent memory, and the host file system. The GitHub advisory scores this Critical (Common Vulnerability Scoring System (CVSS) 9.9 by the published vector; the 10.0 reported by the CVE Numbering Authority (CNA) is a rounding artifact or CNA scoring error — see below). No confirmed in-the-wild exploitation and no public proof-of-concept code exist as of February 20, 2026. Upgrade to 1.39.4 immediately and implement a schema-based field allowlist at the filter evaluation boundary, independent of the patch.
Prefer video? This 12-minute walkthrough covers how eval injection reaches AI agent memory via Semantic Kernel.
More videos on related security topics on our YouTube channel.
The Pattern We Keep Getting Wrong
The pattern is the Framework-Internal Eval Surface. It appears when an AI agent framework’s query or filter interface accepts caller-supplied strings and resolves them through the host language’s native attribute access mechanism — getattr(), eval(), or equivalent — rather than against an isolated, schema-constrained evaluator. Every mature database system enforces the separation between query language and host runtime, an isolation earned through decades of SQL injection incidents. AI agent framework authors reached for host-language dynamism rather than a purpose-built evaluator, inheriting the query interface pattern without the isolation guarantee that makes it safe.
The invariant violated: a caller’s ability to name a field in a filter expression is not equivalent to selecting from a known-safe schema. Without isolation, naming a field is equivalent to accessing the Python runtime’s own object model. The correct principle: any interface that accepts caller-supplied strings and resolves them via language-native attribute access is an eval surface, regardless of how it is documented.
Why This CVE Matters: Three Frameworks, Fourteen Months
CVE-2026-26030 was published February 10, 2026, affecting Semantic Kernel Python SDK versions prior to 1.39.4. InMemoryVectorStore — described by Microsoft as an “out-of-the-box connector” for agent memory storage — is used in production, as the advisory’s own workaround language suggests. The fix shipped same-day in python-1.39.4 via PR #13505, discovered by researchers amiteliahu, doredry, and urioren. Two CVSS scores exist: the GitHub CNA rates it 10.0; the GitLab advisory aggregator and independent recalculation from the published vector (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H) yield 9.9. The CVSS 3.1 formula produces 9.9 — a score of 10.0 with Scope:Changed requires PR:N, not PR:L — so the GitHub CNA score appears to be a rounding artifact or CNA scoring error. The National Vulnerability Database (NVD) has not yet scored this CVE as of February 20, 2026. I use 9.9 throughout; Critical either way.
“blocking use of dangerous attribute names that must not be accessed in filter expressions”
GitHub Advisory GHSA-xjw9-4gw8-4rqx, Fix Description (2026-02-10)
“Avoid using InMemoryVectorStore for production scenarios.”
GitHub Advisory GHSA-xjw9-4gw8-4rqx, Workaround Statement (2026-02-10)
This is the third occurrence of the pattern in fourteen months. LangChain CVE-2025-68664 (December 2025, CVSS 9.3) allowed LLM-influenced data to be treated as trusted framework objects during serialization — same class, different component. LlamaIndex CVE-2025-1793 (early 2025, Critical), analyzed by Endor Labs, exposed SQL injection in vector store interfaces when unvalidated inputs reached SQL query construction.
The Mechanics in Brief
An attacker with any low-privilege authenticated account submits a filter expression containing Python dunder attributes (__class__, __import__, __builtins__) as field selectors. The filter evaluation path resolves these through Python’s object attribute access mechanism rather than against the record schema, traversing the object model to reach Python’s runtime introspection infrastructure and enabling arbitrary code execution as the agent process OS user. The vulnerability is classified under the Common Weakness Enumeration (CWE) as CWE-94 (Code Injection) at root cause, with CWE-20 (Improper Input Validation) as the contributing weakness and CWE-693 (Protection Mechanism Failure) as the resultant weakness. See the GitHub security advisory for full technical detail.
Pattern: The Framework-Internal Eval Surface
Preconditions: An AI agent framework filter or query interface maps caller-supplied strings to the host language’s object access mechanism; an attacker-reachable authenticated caller can submit filter expressions. How it enables attack: Field selector strings containing host-language introspection primitives are resolved as Python object paths, reaching the runtime’s import system and enabling RCE. Detection signals: Any dunder attribute string (__class__, __import__, __builtins__, __mro__, __subclasses__, and others — the dangerous set is not exhaustively enumerable) appearing as a filter parameter in request or API gateway logs; unexpected process behavior; Software Composition Analysis (SCA) scanner alerts for Semantic Kernel Python SDK < 1.39.4. Mitigations: Upgrade to SDK >= 1.39.4; implement a static schema-based field allowlist at the application layer before filter expression construction; apply SQL-parameterization-equivalent injection review to all AI agent framework filter and query APIs. Residual risk: Application-layer code constructing filter expressions outside the framework’s evaluation path may re-introduce the pattern independently of the patch.
What Went Wrong: The Architectural Failure
The InMemoryVectorStore filter resolved caller-supplied field names through Python’s attribute access mechanism — the same mechanism that gives access to __class__, __import__, and the rest of Python’s runtime object model. This is not a code bug in the ordinary sense: the code does exactly what the design specified. The design placed the “query evaluator” inside the trusted Python execution context rather than outside it. Any correct implementation of that design is vulnerable by construction.
Contrast this with how SQL parameterization works: the query is parsed and evaluated by a separate engine with no path to the host language’s runtime. The isolation between query language and host runtime is the structural guarantee that makes SQL injection impossible within the parameterized query boundary. InMemoryVectorStore’s filter had no equivalent boundary; caller-supplied field names reached Python’s object resolution layer, which cannot distinguish between “select this schema field” and “access this Python runtime primitive” when presented with a string like __builtins__.
The fix applies a blocklist of dangerous attribute names — correct and pragmatic, but applied to a design that fundamentally lacks the isolation that would make such blocklists unnecessary. A blocklist can be bypassed if an attacker discovers names not on the list; an allowlist, which rejects anything not explicitly permitted, cannot. The architectural correct is an isolated evaluator: a purpose-built parser whose grammar is limited to schema field names and comparison operators, with no path to the Python runtime.
Threat Model Implications
Teams typically review AI agent systems for prompt injection and output handling, treating vector store filter APIs as infrastructure. CVE-2026-26030 establishes that filter() interfaces mapping caller-supplied strings to host-language objects are code execution surfaces. Extend injection review to every AI agent framework component accepting caller-controlled strings.
Authentication is not a sufficient gate. PR:L means any standard user — trial account, registered user, compromised credential — can reach the filter injection surface. Apply authorization at the filter parameter level, enforcing a static, developer-authored schema allowlist regardless of caller authentication status; a dynamically constructed allowlist derived from stored data can itself be attacker-influenced. Authorization (what a caller is permitted to do) and input validation (ensuring submitted values conform to a schema) are distinct controls at different layers — both are required.
In-process storage does not carry lower risk when the query interface is the attack surface. Eliminating the network hop does not change the semantics of a filter that resolves caller-supplied strings against host-language objects.
If an agent constructs filter expressions from LLM-generated text, the available evidence suggests prompt injection chains with LLM08:2025 exploitation to reach RCE — plausible but not a confirmed exploitation technique for this CVE. Treat LLM output as untrusted to all downstream filter parameters; the correct implementation is structured output with schema-validated field names (a Pydantic model constraining field_name to an Enum of valid schema identifiers, not freeform text).
What Correct Looks Like: The Isolation Principle
A filter interface designed against this pattern validates all caller-supplied tokens at the application layer — before those strings are used to construct a filter expression or passed to the filter API — against a static, developer-authored schema allowlist. If the submitted token is not in the allowlist, the query is rejected before the evaluator runs. The allowlist must be immutable at runtime and derived from developer-authored schema definitions, not from stored data or LLM-generated content an attacker might influence. This directly addresses the trust boundary between caller-supplied data and Python’s attribute access layer; a schema-enforced allowlist would have blocked every step of this attack chain.
The complete architectural correct is an isolated evaluator: a purpose-built expression parser with no path to the host language’s runtime. Genuine Python sandbox isolation is harder than it appears; RestrictedPython has a history of bypass vulnerabilities, and a custom Domain-Specific Language (DSL) parser requires significant engineering investment. Least-privilege process isolation — secrets retrieved from a vault at tool-execution time rather than loaded as environment variables at startup — limits blast radius when injection succeeds but does not prevent injection itself.
OWASP Reference Mapping
LLM08:2025 Vector and Embedding Weaknesses
CVE-2026-26030 is a direct LLM08 instance: the exploit targets InMemoryVectorStore’s filter API, bypassing the model entirely. LLM08 frames the retrieval layer as a trust boundary with its own required controls — exactly what this CVE validates. If LLM08 threat modeling has addressed data poisoning but not the filter API as a code execution surface, add that to your next architecture review. OWASP LLM Top 10 2025
A05:2025 Injection
A05:2025 covers attacker-supplied data interpreted as a command rather than data, explicitly including CWE-94 code injection. CVE-2026-26030 maps squarely: the filter path resolves attacker-supplied attribute names as Python object paths, not data tokens. The SQL injection discipline — validate against a schema allowlist, never pass user data directly to an evaluator — applies without modification. OWASP Top Ten 2025
A06:2025 Insecure Design
A06:2025 covers architectural failures where no correct implementation compensates for a missing structural control. InMemoryVectorStore’s filter evaluated caller-supplied expressions inside the trusted execution context — vulnerable by construction. The patch adds a blocklist; the architectural correct requires redesigning the evaluation path. OWASP Top Ten 2025
What Product Teams Commonly Miss
- Does your AI agent’s vector store filter interface constrain callers to a pre-defined allowlist of schema-defined identifiers before those strings reach any evaluation path? (Architectural gap)
- Can any low-privilege authenticated account — standard user, trial account, compromised credential — reach the vector store’s filter API with arbitrary query parameters? (Authentication vs. behavioral trust gap)
- Does any code path construct filter expressions from LLM-generated text or user-supplied input without validating against a strict field allowlist before reaching the filter evaluation layer? (Indirect injection chain gap)
- Is InMemoryVectorStore deployed in production where the filter API is reachable by end users, API clients, or services that could be attacker-controlled? (Deployment scope gap)
- Does your security logging capture filter expression content? If exploitation occurred, would your SIEM (Security Information and Event Management) infrastructure contain the malicious attribute name as forensic evidence? (Detection gap)
- For each AI agent framework component in your stack — memory store, tool executor, retrieval chain, serialization layer — have you asked: can a caller-supplied string reach the host language’s runtime object model through this interface? (Injection review scope gap)
Recommended Actions
Immediate (well-resourced teams)
Upgrade the Semantic Kernel Python SDK to version 1.39.4 across all environments today. Confirm the installed version with pip show semantic-kernel. If any environment cannot be patched immediately, block or require explicit authorization for API calls carrying filter expression parameters to InMemoryVectorStore endpoints. If you consume Semantic Kernel through a third-party vendor product, verify with your vendor that their release incorporates python-1.39.4 or later. Add CVE-2026-26030 to your vulnerability management backlog scoped to the architectural remediation (implementing the schema-based allowlist), not just the patch.
Short-term (mid-maturity teams)
Add InMemoryVectorStore’s filter API to your threat model as an injection surface. Implement a schema-based field allowlist at the application layer: validate any user-supplied or LLM-supplied string against a developer-authored set of valid field names before those strings are used to construct a filter expression or passed to the filter API. The framework patch is a blocklist, not an allowlist — application-layer expression construction may introduce equivalent risks independently. Extend your Software Composition Analysis (SCA) scanning to flag vulnerable Semantic Kernel versions.
Strategic (all orgs, longer horizon)
Add “filter and query interface injection review” as a mandatory step in your threat modeling phase for every AI agent framework component. The question to ask at design time: does this component accept caller-supplied strings and resolve them through the host language’s object model? If yes, it is an injection surface requiring an isolated evaluator or schema-based allowlist as a design requirement. Teams that internalize this principle will catch the next variant before it ships rather than ten days after it is patched.
Scope and Limitations
- This analysis covers InMemoryVectorStore specifically. Other Semantic Kernel Python SDK backends — Azure AI Search, Chroma, Pinecone, Redis, Qdrant, and others — are not named in the advisory and are not known to share this vulnerability. Teams using those connectors should audit their backend’s filter implementation independently.
- This analysis does not cover the Semantic Kernel .NET SDK. CVE-2026-26030 is scoped exclusively to the Python SDK.
- The direct attack vector does not involve the language model. The indirect prompt injection chain (LLM output influencing filter expression construction) is a reasoned inference about a plausible secondary attack path, not a confirmed exploitation technique for this CVE.
- Upgrading to Semantic Kernel 1.39.4 does not eliminate all vector store injection risks. Application code that constructs filter expressions from untrusted inputs in its own logic, or other AI framework components in the same stack, require independent audit and remediation.
Conclusion
The lesson from CVE-2026-26030 is not about Semantic Kernel specifically — it is about a design assumption that is wrong every time it appears: that accepting user-controlled strings and resolving them through the host language’s object model is safe because the interface is labeled “filter” rather than “eval.” SQL developers learned this the hard way a generation ago. AI agent framework developers are learning it again, in Python, in vector store query interfaces. Teams that internalize the isolation principle — that every interface accepting caller-supplied strings and resolving them via language-native attribute access is an injection surface — will apply the right threat modeling question to the next framework component before it ships. That is what separates a team that patches this CVE from a team that would have prevented it.
Frequently Asked Questions
What is CVE-2026-26030?
CVE-2026-26030 is a critical remote code execution vulnerability in Microsoft's Semantic Kernel Python SDK versions before 1.39.4. The InMemoryVectorStore filter API resolved caller-supplied field names against Python object attributes, allowing authenticated attackers to access runtime internals and execute arbitrary code as the agent process user.
Which versions of Semantic Kernel are affected by CVE-2026-26030?
All versions of the Semantic Kernel Python SDK prior to 1.39.4 are affected. The fix shipped in python-1.39.4 on February 10, 2026. The .NET SDK is not affected.
How do I patch or mitigate CVE-2026-26030?
Upgrade the Semantic Kernel Python SDK to version 1.39.4 or later immediately. Additionally, implement a schema-based field allowlist at the application layer to validate caller-supplied strings against developer-authored field names before they reach the filter evaluation path. The framework patch applies a blocklist, but an application-layer allowlist provides defense in depth.
Is CVE-2026-26030 being actively exploited?
No confirmed in-the-wild exploitation and no public proof-of-concept code exist as of February 20, 2026. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog and has not yet been scored by the National Vulnerability Database.
Why is the Framework-Internal Eval Surface a recurring design pattern?
AI agent framework authors adopt query expression interfaces from database systems without inheriting the isolation guarantee that separates query language from host runtime. Three major frameworks — Semantic Kernel, LangChain, and LlamaIndex — shipped variants of this pattern within fourteen months, all allowing user-supplied strings to reach host-language execution contexts.
Related Reading
- Compile-Time Enforcement at a Runtime Boundary: n8n’s TypeScript Type System Sandbox Escapes (2026-02-17) — Five CVEs in n8n’s expression sandbox. Same architectural anti-pattern class: a framework trusted the host language’s own mechanisms (TypeScript type annotations) as a runtime security boundary. Both articles map to OWASP A06:2025 Insecure Design.
- Training-Reversible Safety Alignment: Why LLM Guardrails Are Not Security Boundaries (2026-02-15) — Covers the broader principle that AI safety controls implemented within the layer they are meant to protect can be reversed or bypassed. Both articles examine cases where a framework’s design placed security enforcement inside the trusted execution context rather than outside it.
References
- GitHub Advisory GHSA-xjw9-4gw8-4rqx — CVE-2026-26030, Microsoft Semantic Kernel Python SDK (2026-02-10)
- PyPI — semantic-kernel package page (accessed 2026-02-20)
- GitHub Release python-1.39.4 — microsoft/semantic-kernel (2026-02-10)
- Microsoft Learn — Semantic Kernel InMemoryVectorStore Connector (Preview, accessed 2026-02-20)
- GitLab Advisory Mirror — CVE-2026-26030, semantic-kernel (accessed 2026-02-20)
- GitHub Advisory GHSA-c67j-w6g6-q2cm — LangChain CVE-2025-68664 (2025-12)
- NVD — CVE-2025-1793, LlamaIndex SQL Injection
- Endor Labs — CVE-2025-1793 LlamaIndex Analysis
- OWASP Top 10 for LLM Applications 2025
- OWASP Top Ten 2025