The first of its kind: how one unbounded request body became a denial-of-service class across every major MCP SDK
---
title: "The first of its kind: how one unbounded request body became a denial-of-service class across every major MCP SDK"
published: true
description: "In April 2026 I reported CVE-2026-39313. Six months later the same flaw had been found and patched in the official Python, Java, Go, Ruby, PHP and TypeScript MCP SDKs. Here is the full class, and why most scanners still cannot see the worst of it."
tags: security, mcp, ai, devsecops
---
The one-line version
In April 2026 I reported CVE-2026-39313, a denial-of-service flaw in an MCP server framework. It was the first CVE of its kind: an unbounded HTTP request body, CWE-770, that lets a single unauthenticated request exhaust a Model Context Protocol server's memory and take it offline.
Over the next six months the identical flaw was found and patched in at least nine more MCP projects, including the official Python, Java, Go, Ruby, PHP and TypeScript SDKs. A third-party analysis in July called it "a new vulnerability category." By October two of those CVEs sat in the SDKs that the whole ecosystem is built on, together serving close to half a billion downloads a month.
This is the story of that class: how far it spread, who patched and who is still exposed, and why the two worst ones are effectively invisible to the scanners most teams rely on.
Every claim below links to a primary source.
What the bug actually is
MCP servers speak over an HTTP transport: Streamable HTTP, Server-Sent Events, and OAuth routes. To handle a request, the server reads the request body into memory before it does anything else.
The flaw is simple and brutal. The read loop has no size limit. It keeps appending chunks to a buffer until the client stops sending or the process dies. There is no authentication in front of it, because the body is read before any auth check runs. So an attacker who can reach the endpoint sends one large POST, or a slow endless stream, and the server allocates memory until it is killed by the OOM reaper. One request, one dead server, no credentials required.
This is CWE-770, allocation of resources without limits. It is not exotic. That is exactly why it turned up everywhere.
CVE-2026-39313: the first one
The first public advisory of this class was in mcp-framework, a popular TypeScript framework for building MCP servers.
In versions 0.2.21 and below, the readRequestBody() function in the HTTP transport concatenated body chunks into a string with no cap. The framework even had a maxMessageSize configuration value, but readRequestBody() never referenced it. The limit existed on paper and was never enforced in code. A single large POST to /mcp crashed the server.
I reported it, it was fixed in 0.2.22, and the advisory published on 16 April 2026.
- Advisory (GitHub, GHSA-353c-v8x9-v7c3): github.com/QuantGeekDev/mcp-framework/security/ad…
- CVSS 4.0 8.7 (High), CWE-770
At the time it looked like one framework's mistake. It was not.
It was not a bug. It was a pattern.
Here is the timeline of the same unbounded-body denial-of-service turning up across the MCP ecosystem, as advisories and patches landed through 2026:
- 16 April — mcp-framework, CVE-2026-39313 (the first).
- April to June — Google's MCP Toolbox for Databases had the identical io.ReadAll with no limit, reported four days after my advisory and fixed in June. No advisory, no CVE.
- July — the official Go SDK added a request-body cap, shipped as OOM protection in its release notes, with no advisory and no CVE.
- 30 July — the Ruby SDK, CVE-2026-67432. A 512 MB POST grew a worker from 44 MB to 1.66 GB. Fixed with a 4 MiB default cap.
- 19 August — the PHP SDK, CVE-2026-53965, the client-side version: an unbounded SSE buffer. The Java SDK shipped a matching client-side SSE fix the same day.
- 16 September — rmcp, the Rust SDK, CVE-2026-63128.
- 11 October — mcp-go, CVE-2026-108859.
- 14 October — the official Python SDK, CVE-2026-109527, and the official Java SDK, CVE-2026-108395. Both credited to me among the reporters.
- 20 and 27 October — the official TypeScript SDK, CVE-2026-111768 and a follow-up advisory.
Nine-plus independent projects. The same root cause. The same fix every single time: a default body-size cap, almost always 4 MiB.
In July an independent write-up looked at this and called CVE-2026-39313 the first documented denial-of-service against the MCP HTTP transport and "a new vulnerability category." That is the right framing. This was not a run of unrelated bugs. It was one design gap in how MCP transports read input, replicated across every language the protocol ships in.
The two that carry the protocol
Most of the class lived in frameworks and bindings. Two of them did not. They were in the reference SDKs that nearly every MCP deployment imports.
CVE-2026-109527, the official Python SDK (mcp). In versions before 1.29.1, and in the 2.0 pre-releases through 2.0.1, the Streamable HTTP session manager, the SSE message endpoint, and the OAuth authorization-server routes all buffered complete request bodies with no maximum size. An unauthenticated remote client could send a large declared or streamed body that consumed several times its own size in process memory, and repeat it until the server died.
- Advisory (GHSA-fmmv-w9g8-j3gc): github.com/modelcontextprotocol/python-sdk/securi…
- Fixed in 1.29.1. CVSS 7.5 (High), CWE-770.
- The mcp package serves over 235 million downloads a month on PyPI.
CVE-2026-108395, the official Java SDK. Unbounded request-body reads in the mcp-core HTTP server transports, same class, same impact.
- Advisory (GHSA-4x8c-5vv7-973f): github.com/modelcontextprotocol/java-sdk/security…
- CVSS 7.5 (High), CWE-770.
For scale: the official TypeScript SDK pulls around 257 million downloads a month, the Python SDK 235 million. When the flaw sits in the SDK rather than a single server, every server built on that SDK inherits it the moment it exposes an HTTP transport.
Who patched, ->
Red Hat rated CVE-2026-109527 Important, assessed 44 of its products, and issued three errata:
- RHSA-2026:92510 (OpenShift AI 3.4), RHSA-2026:92666 and RHSA-2026:92667 (Satellite 6.19 and 6.18).
- Of the 44 products assessed, 35 are affected, 6 not affected, 3 marked will-not-fix.
- access.redhat.com
Debian tracks the same CVE against python-mcp at severity grave, and at the time of writing the package in unstable is still unfixed.
- bugs.debian.org
Downstream products started bumping their pins through October: OpenMetadata merged its upgrades, Red Hat's Open Data Hub opened fix PRs, and several hundred automated "bump mcp" pull requests have landed across GitHub since the advisories went live.
So the serious operators with security teams are moving. The question is everyone else.
The specification still does not require this
For all the patching, the root cause has never been closed at the design level. As of early November 2026 the MCP security best-practices document still contains no guidance on request-body size limits. Every SDK solved it independently, with its own default, because the specification never told them to. That is why the same fix had to be rediscovered six, seven, eight times over.
The MCP server security guidance that does exist, including the National Security Agency and CISA information sheet on MCP, discusses resource-exhaustion denial of service as a general risk but points implementers at no concrete control for this. The one place that could stop the whole class at the design level still does not mention it.
The blind spot: most scanners cannot see the worst two
This is current as of 3 November 2026, and it may change the day the databases catch up. Check it yourself.
CVE-2026-39313, the npm one, has a full global GitHub advisory. It is in OSV, it is in npm audit, and a scan of a vulnerable project flags it.
The two SDK CVEs do not behave the same way. CVE-2026-109527 and CVE-2026-108395 exist only as repository-level advisories on the Python and Java SDK projects. They were never promoted into the global GitHub Advisory Database. The downstream effect is a chain of blindness:
- They are absent from the global GitHub advisory mirror, so GitHub Dependabot does not alert on them.
- They are absent from OSV, so osv-scanner and everything built on OSV misses them. Querying a vulnerable mcp version returns the other 2026 CVEs but not this one.
- They have no record in the PyPA advisory database, so pip-audit finds nothing.
- NVD lists both as "Awaiting Analysis" with no version data, so even NVD-driven scanners have no range to match on.
The practical result: a server running a vulnerable mcp package can be scanned by pip-audit, osv-scanner, Dependabot, or a popular MCP-specific scanner that wraps pip-audit, and come back clean for the denial-of-service flaw. The patch shipped, the advisory was written, and the machine-readable plumbing that is supposed to warn people never carried it.
The enterprise distribution trackers, Red Hat, Debian and SUSE, do carry it, because they ingest from their own CNA and NVD feeds. Red Hat has even published a machine-readable VEX file for it. But the developer-facing supply-chain tools that most teams actually run do not. If you depend on pip-audit or Dependabot to tell you about this, right now they will not.
What an attacker gets, and who is at risk
You are exposed if you run an MCP server that:
- exposes an HTTP-based transport (Streamable HTTP or SSE), as opposed to stdio only, and
- is reachable by any client you do not fully trust, which includes the public internet, a shared internal network, or a browser-reachable origin, and
- runs a vulnerable version of the framework or SDK below.
The attack needs no authentication, no credentials, and no user interaction. One oversized or endless request crashes the process. Repeat it and the service stays down. It is trivially scriptable. There is no data theft here, the impact is pure availability, but for an agent backend that other systems depend on, taking it offline on demand is the whole game.
Stdio-only servers and deployments already sitting behind a reverse proxy with its own request-body limit are not exposed in the same way. That proxy limit is also your fastest mitigation while you patch.
The fix
Upgrade. The fixed versions:
- mcp-framework (npm): 0.2.22 or later.
- MCP Python SDK (mcp on PyPI): 1.29.1 or later. The fix adds max_request_body_size with a DEFAULT_MAX_REQUEST_BODY_SIZE of 4 MiB in the transport security layer.
- MCP Java SDK: the patched mcp-core release.
- MCP Go SDK: v1.7.0 or later, which enforces DefaultMaxRequestBodyBytes of 4 MiB.
- Ruby SDK (mcp gem): 0.23.0 or later.
- PHP SDK, Rust rmcp, mcp-go, TypeScript SDK: upgrade to the latest; all shipped the same body-size cap through the autumn.
If you cannot upgrade immediately, put a reverse proxy in front with a client body limit (for example nginx client_max_body_size), and make sure your HTTP transport is not reachable from untrusted networks. Where your SDK exposes a configurable limit, set it explicitly rather than trusting the default, especially if you legitimately handle large payloads.
How to find it in your estate
- Inventory every MCP server you run and whether it exposes an HTTP transport or stdio only.
- For Python, do not trust pip-audit alone for this one today. Check the installed mcp version directly: anything below 1.29.1 is vulnerable.
- For npm, npm audit will catch mcp-framework below 0.2.22.
- For Java and Go, check the SDK version against the fixed releases above, because the advisories are not yet in the global databases your SCA tooling reads.
- Grep your own HTTP handlers for the pattern itself: a body read with no length cap, io.ReadAll(r.Body) in Go, request.body.read with no bound in Ruby, a string += chunk loop in Node, before any size check. If you wrote a custom transport, you may have reproduced the class yourself.
The lesson
The MCP ecosystem grew faster than its security guidance. A single gap in how transports read input became a denial-of-service class that reached every major SDK in the protocol, and the one control that prevents it is still not written into the specification.
The fixes exist now. The specification guidance still does not. And for the two CVEs in the core SDKs, the automated warning system that the rest of us depend on is, as of today, silent. If you run MCP in production, do not wait for a scanner to tell you. Check the versions yourself.
References
- CVE-2026-39313, mcp-framework: github.com/QuantGeekDev/mcp-framework/security/ad…
- CVE-2026-109527, MCP Python SDK: github.com/modelcontextprotocol/python-sdk/securi…
- CVE-2026-108395, MCP Java SDK: github.com/modelcontextprotocol/java-sdk/security…
- Red Hat, CVE-2026-109527: access.redhat.com
- Debian tracker (grave), python-mcp: bugs.debian.org
- OWASP AISVS, MCP transport payload-size control citing CVE-2026-39313: github.com/OWASP/AISVS/blob/main/1.0/research/cha…
---
Raza Sharif, CyberSecAI Ltd. Reported CVE-2026-39313 and is credited on CVE-2026-109527 and CVE-2026-108395. All vulnerabilities were handled through coordinated disclosure and are fixed in the versions listed above. Contact: contact@agentsign.dev.
Debating How to Threat Model Terraform Infrastructure Code: Simon Kang and Srdan Reljic at Global AppSec USA 2026
Terraform defines a company's cloud infrastructure in code, so one pull request can open an S3 bucket to the internet or widen a firewall rule before anyone reviews the design.
Because the infrastructure exists as code, tools can read each Terraform change and generate a threat model from it automatically. Teams building those tools have to decide how much of the analysis to hand to an LLM.
At SecretCon in June 2026, Srdan Reljic and Raj Annaladasu presented an AI agent that reads Terraform, flags risky settings such as open S3 buckets, then maps each finding to MITRE ATT&CK.
Annaladasu has since moved every security decision in his pipeline to deterministic code. LLMs now only explain findings, map them to frameworks and suggest fixes.
In their Global AppSec USA 2026 debate, "OWASP by Design: Debate/panel for Terraform", on Thursday, November 5 at 12:00 p.m. in Bayview A, Simon Kang and Srdan Reljic hold a 15-minute discussion on Terraform threat modeling.
Speakers:
- Simon Kang, Principal TPM, Enterprise AI, Snowflake
- Srdan Reljic, Associate Partner, IBM Consulting, Americas
The debate follows Annaladasu's talk, "From Terraform Plan to Attack Paths: PyTM Threat Modeling in CI/CD with LLMs on a Leash," in the same room at 11:15 a.m.
Simon Kang is Principal Technical Program Manager for Enterprise AI at Snowflake and describes himself as a cybersecurity educator. His work connects threat modeling and AI governance with controls that developers can build, which reviewers can then assess.
His interests include agent identity, retrieval authorization and tool-call controls. He co-presents "Threat Modeling AI Agents That Can Act: Identity, Retrieval, and Tool-Call Controls" with Annaladasu on Thursday at 3:15 p.m. in Bayview A.
Srdan Reljic is an Associate Partner at IBM Consulting, Americas. His work applies cloud-native and open-source technology to build security into every layer of a system.
His interests include secure developer enablement, platform engineering and GenAI security. He previously worked as Business Development Executive for Cloud Native Build Americas at IBM.
The SecretCon talk he co-presented describes an agent that turns Terraform into a resource graph and feeds code-level fixes back into CI/CD. It also maps findings to CIS Benchmarks.
To go deeper on the topic, start here:
- SecretCon 2026: AI-Driven Terraform Threat Modeling (Reljic and Annaladasu)
- OWASP pytm on GitHub
- OWASP Developer Guide: pytm
- Checkov on GitHub
Cloud and platform teams deciding how far to trust AI in their infrastructure security reviews will hear two views from people who build these systems.
Would you let an LLM decide whether a Terraform change is risky, or only explain a decision a deterministic tool already made?
2 points · 1 comment
Turning Terraform Plans Into Attack Paths Without Letting an LLM Make the Security Calls: Raj Annaladasu at Global AppSec USA 2026
Infrastructure-as-code scanners such as Checkov and tfsec flag individual misconfigurations in Terraform, but they do not show how those misconfigurations connect into an attack path.
Raj Annaladasu built a pipeline that turns a Terraform plan into an executable OWASP pytm threat model on every pull request. Pytm is OWASP's framework for writing threat models as Python code.
His first version let an LLM generate the threat model itself. That cost the repeatability and traceability a CI/CD pipeline needs, since the same plan could yield different results on different runs.
In his Global AppSec USA 2026 talk, "From Terraform Plan to Attack Paths: PyTM Threat Modeling in CI/CD with LLMs on a Leash", on Thursday, November 5 at 11:15 a.m. in Bayview A, Raj Annaladasu walks through the current design.
Speaker: Raj Annaladasu, Staff Customer Success Engineer, Palo Alto Networks
The pipeline builds a typed graph of the Terraform resources and generates data flow diagrams from it. It also infers IAM relationships that Terraform never states explicitly.
Every security decision in the current design is deterministic. LLMs only explain findings, map them to security frameworks, suggest fixes and document attack paths.
Every AI annotation must point to real evidence in the plan, or the pipeline drops it.
The session compares the pipeline live against Checkov, tfsec and a pytm-only approach. It includes examples where AI helped, along with examples where it did not.
It also demonstrates prompt injection hidden in Terraform comments steering AI tooling, then the safeguards against it. Attendees leave with an architecture they can build.
The session repeats as a hands-on OWASP Project Demo Lab on Friday, November 6 at 1:15 p.m. in Golden Gate. A 15-minute debate on Terraform with Simon Kang and Srdan Reljic follows this talk in Bayview A at 12:00 p.m.
Raj Annaladasu is a Staff Customer Success Engineer at Palo Alto Networks, focused on application, cloud-native, software supply chain and AI security. His work includes risk assessments, static analysis and software composition analysis.
With Srdan Reljic of IBM Consulting, he presented "AI-Driven Terraform Threat Modeling" at SecretCon in June 2026. That earlier version mapped Terraform findings to MITRE ATT&CK and CIS Benchmarks.
He also co-presents "Threat Modeling AI Agents That Can Act: Identity, Retrieval, and Tool-Call Controls" with Simon Kang on Thursday at 3:15 p.m. He then joins a debate on threat modeling agents at 4:00 p.m.
The OWASP Developer Guide explains how pytm turns a model written in Python into data flow diagrams, sequence diagrams and threat reports. Aqua Security has folded tfsec into Trivy and published a migration guide.
To go deeper on the topic, start here:
- SecretCon 2026: AI-Driven Terraform Threat Modeling (Reljic and Annaladasu)
- OWASP pytm on GitHub
- OWASP Developer Guide: pytm
- Checkov on GitHub
- tfsec to Trivy migration guide
Cloud security engineers who already scan Terraform in CI will see how to connect isolated findings into attack paths.
Does your Terraform scanning show how two low-severity findings combine, or only list them separately?
2 points · 1 comment
A Patch-to-Score CTF You Can Run From a Laptop With Docker Compose: Jon McCoy, Brandon Lachterman and Diego Cotelo at Global AppSec USA 2026
The first OWASP CTF at DEF CON 34 in August 2026 drew 60 players, who submitted more than 2,300 patches against six vulnerable OWASP training applications.
Players scored by fixing vulnerabilities rather than exploiting them. Each patch went in as a GitHub pull request, and an automated test judged whether the fix held.
Running a hands-on security event usually means cloud accounts, ongoing bills and custom scoring infrastructure. OWASP CTF in a Box packages the platform behind that event so that any chapter, class or AppSec team can host its own.
In their Global AppSec USA 2026 demo lab, "OWASP CTF in a Box: Host Your Own Security CTF, from a Laptop to the Cloud", on Thursday, November 5 at 10:30 a.m. in Golden Gate, Jon McCoy, Brandon Lachterman and Diego Cotelo walk through the full life of an event on the platform.
Speakers:
- Jon McCoy, Principal Security Architect & Offensive Engineering Specialist, DigitalBodyGuard
- Brandon Lachterman
- Diego Cotelo, Head of Infrastructure and Security, Crowder
The platform turns a free GitHub organization into a complete event, with team registration, a live leaderboard, an organizer console and automated scoring. It runs on a single laptop or VPS with Docker Compose, or deploys to fly.io or AWS as the event grows.
Its modules include Secure Development, where participants fork a deliberately vulnerable app to score by fixing it, along with quiz and Jeopardy-style challenge boards. AI security challenges hosted elsewhere can feed the same scoreboard.
The demo covers launching an event in minutes, then running it live: opening registration, scheduling the scoring window, managing teams or hints, and freezing scoring. It ends with customizing branding and contributing new challenge modules.
Jon McCoy is Principal Security Architect & Offensive Engineering Specialist at DigitalBodyGuard, which he founded. He built some of the first tools for reverse engineering .NET applications and presented on attacking them at DEF CON 18 in 2010.
Diego Cotelo is Head of Infrastructure and Security at Crowder in Montevideo, Uruguay. He has more than 15 years of experience across infrastructure, security consulting and cloud architecture. He previously worked as a Staff Engineer at Fingerprint and a Cloud Architect at Caylent.
Cotelo co-built the OWASP CTF at DEF CON 34. He co-leads CTF in a Box with McCoy and Chris Maenner.
The OWASP project page lists CTF in a Box as an Incubator project written in TypeScript, with 321 challenges across six training targets. The DEF CON 34 event site breaks those down by app, from 110 challenges in VulnerableApp to 9 in VAmPI.
The how-to-play guide walks through the scoring loop with a real example: a Juice Shop SQL injection in routes/login.ts, fixed with bind parameters.
To go deeper on the topic, start here:
- OWASP CTF in a Box on GitHub
- OWASP CTF in a Box project page
- OWASP CTF at DEF CON 34: challenges and format
- How the patch-to-score CTF works
OWASP chapter leaders, educators and AppSec teams who want to run a defense-focused CTF without building scoring infrastructure are the audience for this demo.
Would your developers learn more from a CTF where they fix bugs or one where they exploit them?
2 points · 1 comment
From 200 Container CVEs to the Few Dockerfile Lines Worth Fixing: Advait Patel at Global AppSec USA 2026
A container image scan typically returns more than 200 CVEs, most of them noise, with no indication of which few Dockerfile lines a developer should change.
According to Advait Patel's session description, those reports get ignored. Someone spends half a day looking up each CVE, then files the rest as accepted risk.
OWASP DockSec, which Patel created, sits on top of existing scanners rather than replacing them. It runs Trivy, Hadolint and Docker Scout locally. An LLM then correlates the results, removes duplicates, then ranks what matters for the specific setup.
In his Global AppSec USA 2026 demo lab, "DockSec: Closing the Gap Between What Your Scanner Finds and What You Actually Fix", on Thursday, November 5 at 10:30 a.m. in Golden Gate, Advait Patel runs real Dockerfiles through the tool live.
Speaker: Advait Patel, Senior Site Reliability Engineer, Broadcom
The demo includes Dockerfiles that pass standard scanning clean. For each issue DockSec surfaces, it gives a plain-English explanation along with the exact line-level fix.
DockSec produces a 0 to 100 security score for tracking posture over time. It exports HTML, PDF, JSON, CSV or Markdown reports, so security and development teams share one artifact.
Only scan metadata leaves the machine; image contents never do. DockSec works with OpenAI, Anthropic or Google Gemini models, or fully locally through Ollama with no API key, and it runs in CI/CD on every build.
Attendees can bring their own Dockerfiles. Patel also gives a 30-minute DockSec project showcase on Thursday at 2:45 p.m. in Seacliff CD.
Advait Patel is a Senior Site Reliability Engineer at Broadcom in Chicago and a Docker Captain. He has more than eight years of experience in cloud-native architecture, container security and DevSecOps. He is a Google Developer Expert for Google Cloud and AI.
He is a founding member of the OWASP AI Vulnerability Scoring System (AIVSS) project. He has co-authored two Springer books on Google Cloud security, along with Cloud Security Alliance guidance on securing LLM workloads.
His speaking credits include QCon AI Boston, SANS CloudSecNext, OWASP SnowFROC, PlatformCon and the Linux Security Summit North America.
The OWASP DockSec project page shows it reached OWASP Lab status in June 2026, with Arkadii Yakovets as co-leader. It also outputs SARIF and CycloneDX SBOM files. Secrets are redacted before any content reaches an AI provider.
SC World reported about 17,000 PyPI downloads. It also described one startup that cut production CVEs by 78 percent, from about 22 to about 5 per month, while triage time per image fell from about 45 minutes to about 6.
To go deeper on the topic, start here:
- ISACA Podcast: Your Containers Are Probably Full of Holes: Fixing Docker Security with AI (Advait Patel)
- OWASP/DockSec on GitHub
- Help Net Security interview with Advait Patel on DockSec
- SC World: DockSec adoption and triage-time results
- docksec on PyPI
Platform engineers who own container images, and who are tired of untriaged scanner output, are the audience for this demo.
How many open container CVEs does your team currently carry as accepted risk?
3 points · 1 comment
Turning AI Risks Into Testable Security Requirements With OWASP AISVS: Rico Komenda and Jim Manico at Global AppSec USA 2026
OWASP's AI Security Verification Standard reached version 1.0 in June 2026, with 12 chapters of testable requirements for applications built on models, LLMs and AI agents.
Most AI security guidance describes risks at a high level. Engineering teams deciding whether an AI-enabled application is secure enough to ship need requirements they can check one by one.
AISVS adapts the idea behind OWASP's Application Security Verification Standard (ASVS) for web apps: security should be verifiable and measurable. It turns AI risks into requirements a team can use in design review, testing, procurement and production readiness.
In their Global AppSec USA 2026 talk, "OWASP AISVS: Bringing Order to AI Security Chaos", on Thursday, November 5 at 10:30 a.m. in Seacliff CD, Rico Komenda and Jim Manico explain how the standard was built, along with how teams can apply it.
Speakers:
- Rico Komenda, Senior Product Security Engineer
- Jim Manico, Founder, Manicode Security
The speakers argue that security practice still assumes deterministic software, while AI systems produce probabilistic output and make decisions on the fly. AISVS keeps the parts of conventional secure development that still apply, then adds new verification categories where they do not.
The new categories cover prompts, models, agents, training data, retrieval-augmented generation (RAG), tool use, output handling and AI governance. The talk also shares lessons from building the standard, including where it differs from traditional AppSec.
The AISVS project page lists 12 chapters, from training data integrity through MCP security to monitoring and anomaly detection. Requirements fall into three levels: a baseline, a level for production or customer-facing apps, and a level for safety-critical or regulated systems.
Rico Komenda is a Senior Product Security Engineer who works on the attack surface of AI-integrated systems and secure agentic development. He is one of the AISVS project leaders, along with founder Jim Manico, Otto Sulin and Russ Memisyazici.
Komenda contributes to the OWASP GenAI Security Project. He previously worked as a Senior Security Consultant at adesso SE.
At Global AppSec EU 2025 in Barcelona, he co-presented "Builders and Breakers: A Collaborative Look at Securing LLM-Integrated Apps," taking the red team side with live data poisoning demos. His other talks include "Pentesting LLM-integrated applications" at JavaLand 2025.
Jim Manico founded Manicode Security, which trains developers in secure coding. He founded AISVS and wrote "Iron-Clad Java: Building Secure Web Applications." He also co-leads OWASP ASVS along with the OWASP Cheat Sheet Series.
Komenda also presents "Security Chaos Engineering for AI Application Architectures" on Thursday at 1:45 p.m. The two speakers then run a hands-on AISVS assessment workshop on Friday, November 6 at 10:30 a.m. in Golden Gate.
The pair first presented AISVS together in a lightning talk at Global AppSec EU 2026 in Vienna, before version 1.0 shipped. LRQA Cyber Labs has since published a chapter-by-chapter overview of the 1.0 release.
To go deeper on the topic, start here:
- OWASP AISVS GitHub repository
- OWASP AISVS project page
- LRQA Cyber Labs: OWASP AISVS 1.0 chapter-by-chapter overview
- VirtusLab: OWASP AISVS 1.0 walkthrough
- ITSPmagazine interview with Jim Manico on AISVS
AppSec teams asked to sign off on AI features, without a checklist that fits them, will find one here.
What would your team check first before approving an AI feature for production?
2 points · 1 comment
That the American Osteopathic College of Radiology [aocr.org](aocr.org) have such an incredible interest in our main Cornucopia repository (owasp/cornucopia) on Github is a mystery to me. Does anyone care to elaborate?
#appsec #security #osint
When GitHub Went Dark: How OWASP BLT Found a New Home
50+ repositories went offline in the middle of Google Summer of Code. Here's how our community kept moving, and how an unexpected project became our new home.
This one is a bit of a rollercoaster, so buckle up. 🎢
The calm before the storm
It was the middle of Google Summer of Code (GSoC).
OWASP BLT (Bug Logging Tool) had more than 50 repositories under a single GitHub organization. We had everything from the core application to Slack bots, a browser extension, a hackathon platform, a GSoC tracker, and a long list of tools built and maintained by our contributors.
Things were moving along nicely.
Mentors were reviewing. Contributors were shipping. Leaderboards were updating. The usual open-source chaos, but the good kind.
Then we decided to do some housekeeping.
Good security hygiene, right?
We applied an organization-wide GitHub ruleset to enforce consistent repository protections across all our projects.
A security-focused project enforcing security rules on its own organization.
What could possibly go wrong?
The morning after: everything was gone
We woke up to find our GitHub repositories offline.
All 50+ of them.
And here's where things got confusing.
At almost exactly the same time, GitHub itself was experiencing an outage.
So for several hours, we genuinely had no idea what was happening.
Was it our new ruleset? Was something wrong with the BLT organization? Was it GitHub's outage? Or was the timing just a coincidence?
We contacted GitHub support.
Then we followed up.
And followed up again.
Days passed, and we never received a clear explanation for what had happened to our organization.
Mostly, we got silence.
Meanwhile, Google Summer of Code wasn't going to pause for us.
Contributors had active branches. Mentors had pull requests waiting for review. Projects had deadlines.
When developers can't clone repositories or open pull requests, that's more than an inconvenience. It brings development to a halt.
We needed another option.
Plan B: moving to GitLab
Rather than keep waiting for answers, we moved our repositories to GitLab.
We pushed the code, redirected contributors to the new location, and worked on getting everything running again.
Repositories were accessible. CI pipelines were migrated where possible. Contributors could get back to work.
It wasn't the migration we'd planned.
Actually, we hadn't planned a migration at all.
But the community adapted, and development continued.
We still wanted our original GitHub organization restored, of course.
We kept reaching out to GitHub over the following months.
Unfortunately, we still didn't get a clear answer.
An unexpected plot twist: Kaif built a Git forge
Here's where the story gets interesting.
Some time later, we learned that one of our community members, Kaif, had built something of his own.
While we had been dealing with the fallout of losing access to our GitHub organization, Kaif had turned the situation into a project.
He built ForkMesh, a self-hosted Git forge.
Think of it as having your own GitHub-like platform, with:
- Git repositories and code hosting
- Issues and pull requests
- Actions-style CI/CD workflows
- Support for AI agents as first-class collaborators
- The ability to run your own instance
The funny part?
We hadn't set out to build or commission our own Git hosting platform.
We had moved to GitLab to keep things going, and later discovered that someone in our community had built an entirely different option.
So we gave ForkMesh a try.
And it stuck.
From 50+ repositories to one home
Today, OWASP BLT has a very different setup.
Our official source of truth is now git.owaspblt.org, running on ForkMesh.
And we took the opportunity to do something we'd wanted to do for a while: consolidate our projects.
<escape>###</escape> One repository, all our history
Instead of maintaining 50+ separate repositories, BLT projects now live together in one repository, organized into their own folders.
We preserved their commit histories along the way.
That means:
- 45,000+ commits preserved
- 260+ contributors represented
- Projects organized in one place
- One central home for issues, contributions, and development
That's a lot of community history, and we wanted to make sure it came with us.
<escape>###</escape> GitHub is now our mirror
Yes, you read that correctly.
GitHub went from being our primary home to being our backup.
Our repository at OWASP/BLT is now a read-only mirror, automatically synchronized from our forge.
The source of truth is the forge we host.
Funny how things turn around.
<escape>###</escape> GitLab is archived, not forgotten
We didn't just abandon our temporary GitLab home.
Every open merge request was reviewed. Contributions worth bringing forward were merged into the new repository, with the original authors credited.
Other merge requests were closed with explanations.
Open issues were migrated to the forge, with references back to their original locations.
The GitLab repositories remain archived so old links and project history are still accessible.
<escape>###</escape> A little cleanup along the way
We also used the migration as an opportunity to clean up some technical debt.
For example, scheduled data jobs now write to Cloudflare storage instead of filling the Git history with automated bot commits.
A bunch of little improvements that might not have happened otherwise.
Sometimes an unexpected migration gives you a good excuse to fix things you've been putting off.
What this taught us
There are a few lessons we're taking away from the experience.
1. Don't put all your eggs in one platform
GitHub is an important part of the open-source ecosystem, but relying entirely on one platform introduces risks.
Your source code, issues, contributions, and project history represent years of community effort.
Having a backup is inexpensive. Losing access without an explanation can be extremely costly.
We now have much more control over where our work lives.
2. Test organization-wide changes on a smaller scope first
We still don't know exactly what caused our GitHub organization to become unavailable.
It would be unfair to claim the ruleset was responsible without confirmation.
But we learned something important regardless.
When making changes that affect more than 50 repositories, start small.
Test the behavior, understand the impact, and expand gradually.
Because when a large change goes wrong, the consequences can be just as large.
3. Open-source communities are remarkably resilient
This is probably the biggest takeaway.
What kept BLT going wasn't a particular platform.
It was the people.
Contributors continued working. Mentors kept supporting students. The community found alternatives.
And one community member went a step further and built a Git forge that eventually became our new home.
That's the part of open source we love most: people turning problems into opportunities to build something useful.
Come build with us 🐝
If you already contribute to OWASP BLT, or you've been thinking about getting started, our new forge is where the action happens.
👉 Explore the OWASP BLT repository
You can browse the projects, clone the repository, open issues, submit pull requests, and help us improve both BLT and the contributor experience.
We're still learning what works best with our new setup, and we'd genuinely appreciate feedback.
One more thing: we have a world 🌍
Because apparently moving 50+ repositories wasn't adventurous enough, there's also something fun to explore.
The forge comes with its own virtual world.
OWASP BLT has its own hex, complete with:
- A bug terrarium filled with websites that people have reported bugs on. You can walk inside through the door.
- A Hacker House you can enter and explore.
- A road connecting the BLT world to the neighboring ForkMesh world.
It's a playful little addition to what started as a pretty frustrating situation.
👉 Take a walk around the BLT World
---
We started with more than 50 GitHub repositories, lost access to them in the middle of GSoC, moved to GitLab to keep development going, and eventually found a new home thanks to something a community member built.
Not exactly the infrastructure roadmap we'd imagined.
But here we are: 45,000+ commits, 260+ contributors, one forge, and a community still building.
See you on the forge. 🐝
18 reactions
AI Security Testing 101: Prompt Injection and Indirect Prompt Injection
This is the first post in a new series on AI application security testing, following the structure of the OWASP AI Testing Guide's AI Application Testing category (AITG-APP). Each post in the series will take one test from that category and turn it into something practical: what the vulnerability actually looks like, how testers approach it, and what "vulnerable" means in concrete terms.
We're starting where the guide starts: prompt injection, one of the most well-known AI application vulnerabilities, and a class of attack that can underpin many other AI-specific security risks.
---
Direct Prompt Injection (AITG-APP-01)
Prompt injection happens when attacker-controlled input changes an AI application's behavior in a way that conflicts with its intended instructions or security constraints. The input may attempt to make the model ignore higher-priority instructions, reveal information it should not disclose, or perform an action it was not intended to perform.
A useful, though imperfect, analogy is SQL injection: in both cases, attacker-controlled input can influence behavior that the application intended to control. The analogy has limits, however. SQL injection exploits the interpretation of data as executable syntax, while prompt injection arises from the way language models process natural-language instructions and contextual information.
The AITG-APP-01 methodology characterizes a prompt injection in terms of three elements:
- Instructions: what the attacker actually wants the model to do.
- A trigger: the specific phrasing, framing, or encoding intended to cause the model to follow the attacker's instructions rather than its intended behavior.
- Conflict with intent: the injected request conflicts with the application's intended instructions or constraints.
Without that conflict, an unusual or adversarial-looking prompt may simply be a normal request rather than a security-relevant prompt injection.
Prompt injection is also broader than jailbreaking. A jailbreak attempts to bypass safety restrictions, while prompt injection more generally involves attacker-controlled input changing model behavior in an unintended way. An injection can therefore be security-relevant even when it does not produce prohibited content.
Whether an attack succeeds can depend heavily on how the trigger is constructed. That's one reason simple keyword filtering is insufficient on its own. Blocking the phrase "ignore previous instructions" does little against the same underlying idea expressed through role-play, another language, obfuscation, or an encoded representation.
Attack Patterns Worth Knowing
The OWASP guide catalogs a broad set of concrete payload techniques. They can be grouped into a handful of practical patterns:
Persona and role-play framing
Asking the model to "pretend" to be an unrestricted persona so that it treats otherwise disallowed behavior as being in character. A well-known example is the "DAN" jailbreak.
The underlying technique is not limited to DAN. Attackers can construct fictional characters, simulated environments, alternate roles, or hypothetical scenarios intended to change how the model interprets its constraints.
Context manipulation
Telling the model to "forget" previous instructions, attempting to override higher-priority context, or gradually steering the conversation toward a prohibited behavior.
This can include multi-turn approaches in which no individual request appears particularly harmful, but the sequence gradually changes the context presented to the model. "Crescendo" and "echo chamber" style attacks are examples of this broader pattern.
Obfuscation and encoding
Hiding or transforming the attack instruction using techniques such as base64, hexadecimal encoding, reversed text, unusual capitalization, deliberate typos, Unicode manipulation, or other transformations.
The purpose is often to evade filters or exploit differences between what a security control recognizes and what the model can interpret.
The important lesson is that filtering for a fixed set of phrases is not a sufficient defense against a language-based attack surface.
Structural tricks
Taking advantage of how the application or model handles structured inputs, including JSON or other formats, multi-message inputs, or instructions embedded within content that the application expects the model to process.
Structured formats can create additional attack surfaces when applications treat model-generated or model-consumed fields as trusted simply because they conform to an expected schema.
Contradiction and instruction-conflict framing
Presenting multiple competing instructions or asking the model to produce both a normal response and an explicitly contrary response, with the goal of getting it to produce the latter.
The exact payloads are less important than the general testing principle: don't assume that one known jailbreak or injection string represents the entire attack surface.
These techniques are not permanent. Models, applications, and defenses evolve, so a payload that works against one model or configuration may become ineffective against another. That's why testing should combine techniques and repeat requests rather than relying on a single known payload.
Response variability can also matter. In configurations where sampling introduces variability, the same prompt may produce different results across attempts.
---
What Makes a Test Environment Different
Before running tests against a real target, it's worth understanding what's actually in front of you. The architecture and model configuration can significantly affect which techniques are relevant and how the results should be interpreted.
Temperature
Lower temperature generally makes output more repeatable, while higher temperature generally increases variability and diversity.
That matters during testing because a payload that succeeds once may not succeed consistently. Testers should therefore repeat relevant requests and record the configuration used rather than treating a single successful or unsuccessful attempt as definitive.
Temperature does not by itself determine whether a system is secure, and a temperature of zero should not be treated as a universal guarantee of deterministic behavior.
Fine-tuning vs. prompt tuning
Safety and behavioral constraints can be implemented at different layers, including through model training or fine-tuning and through application-level instructions or other steering mechanisms.
This distinction matters during testing because a successful bypass may target different layers of the system. A test might circumvent application-level instructions without demonstrating that the underlying model has changed, for example.
The important question for a tester is therefore not just "did the model comply?" but also "which security control was bypassed?"
Guardrails
Guardrails can be implemented in several ways, including deterministic rules, classifiers, access controls, schema validation, filtering systems, or additional LLM-based checks.
When an application uses an LLM as part of its guardrail system, that introduces another model and potentially another source of variability. Testers should evaluate the guardrail as part of the attack surface rather than assuming that adding another model automatically prevents prompt injection.
Multi-agent setups
When several agents hand work to each other, testers may only see the final output rather than the intermediate prompts, tool calls, and responses.
That makes it harder to determine which agent or handoff an injection actually influenced. Testing therefore benefits from observability into agent-to-agent messages, tool calls, retrieved content, and intermediate decisions wherever possible.
Tool access
A model wired up to scripts, shells, databases, or external APIs can turn a successful injection from unwanted model output into an unauthorized action.
Tool access can therefore substantially increase the potential impact of a prompt injection. However, tool access is not required for an injection to have security impact: unauthorized information disclosure or manipulation of important outputs can also be significant.
---
Indirect Prompt Injection (AITG-APP-02)
Direct injection assumes the attacker is the one providing the malicious input to the AI application.
Indirect prompt injection works differently. The malicious instruction is planted somewhere the AI application will process as external content: a web page, PDF, email, uploaded document, database record, search result, or tool-related content.
The model may then encounter that instruction as part of the context it receives.
The important distinction is not that the model has literally "no way" to distinguish data from instructions. Rather, the model may fail to reliably distinguish untrusted external content from instructions when both are represented in the context it processes.
That creates a different attack surface: the attacker may not need direct access to the AI application if they can influence content that the application will eventually retrieve or process.
Indirect injection can be particularly concerning in applications that automatically retrieve external content, have access to sensitive information, or can take actions through tools.
Concrete Surfaces This Shows Up On
Hidden text in web pages or documents
An attacker can place instructions in content that is difficult for a human reviewer to notice, such as HTML comments, invisible or visually obscured text, document metadata, or other content that is nevertheless extracted and passed to the model.
The important security property is not that the text is literally invisible. It's that the application may process content that the user did not realize would be interpreted by the model.
Structured data fields
A JSON, XML, database record, API response, or other structured input may contain an attacker-controlled field whose value includes an instruction rather than the data the application expected.
For example, a field intended to contain a document summary or description might contain language such as an instruction to ignore the application's task and perform another action.
The fact that the content is valid JSON or XML does not make it trustworthy.
Markdown-based exfiltration
An indirect prompt injection can attempt to make the model include sensitive information in a URL or other externally observable location, including by generating a Markdown image reference or link containing attacker-controlled data.
If the resulting content is rendered or fetched by a downstream component, this can create a data-exfiltration path.
A related technique was demonstrated in the real-world EchoLeak vulnerability affecting Microsoft 365 Copilot. EchoLeak was a multi-stage attack involving indirect prompt injection and data exfiltration under particular conditions; it should not be treated as synonymous with every Markdown-based exfiltration technique.
Encoded payloads
External content can also contain encoded or otherwise obfuscated instructions. The same general filter-evasion issues that apply to direct prompt injection can therefore apply to indirect injection.
Tool metadata and tool poisoning
For AI systems using MCP or similar tool-calling protocols, tool names, descriptions, schemas, metadata, parameters, and outputs can become part of the model's context.
In some client implementations, this information may not be prominently exposed to the user even though it is presented to the model.
An attacker who can control a tool's metadata may therefore attempt to embed instructions into it, for example, instructions telling the model to retrieve information before using the tool.
The security issue is not specific to one metadata field. The broader concern is that the model may treat untrusted tool-related content as instructions.
The common thread is this:
> Anywhere external content reaches the model without a reliable boundary between trusted instructions and untrusted data, there is a potential prompt-injection attack surface.
That boundary is an architectural concern, not merely a question of finding the right payload string.
---
What Counts as a Finding
For both tests, a prompt injection becomes a security finding when attacker-controlled instructions cause behavior that violates the application's intended constraints or security boundaries.
Examples include:
- The model overrides or circumvents intended instructions in a security-relevant way.
- The application discloses information that the model or user should not have access to, such as credentials, API keys, internal configuration, or another user's data.
- The model or connected system performs an unauthorized or harmful action.
- An indirect injection causes the application to treat attacker-controlled external content as an instruction and subsequently produce unauthorized disclosure or action.
For indirect injection specifically, the distinguishing condition is that the security-relevant behavior originates in externally supplied content rather than the user's direct prompt.
Simply following an instruction found in external content is not automatically a vulnerability. For example, if a webpage contains ordinary instructions that are relevant to the user's request and the model follows them as part of legitimately processing that page, there may be no security issue.
The important question is whether attacker-controlled external content can change the application's behavior in a way that violates its intended security or operational constraints.
---
Remediation, in Short
Both tests point toward several overlapping defensive principles.
Separate trusted instructions from untrusted content
Clearly distinguish system/application instructions from user input and external data.
Delimiters and structured context can help the model distinguish these sources, but they should be treated as mitigations rather than a guarantee that prompt injection will never succeed.
Treat external content as untrusted
Validate and sanitize external content before it reaches the model where appropriate. Consider hidden text, encoded instructions, unusual Unicode, metadata, and other forms of content that a human reviewer may not recognize as instructions.
But don't rely on sanitization alone. Natural language is too flexible to make exhaustive filtering a reliable security boundary.
Restrict model privileges
Give the model only the access and capabilities it actually needs.
If a model does not need access to credentials, private files, sensitive databases, or administrative functions, those capabilities should not be available to it merely because the model might request them.
Authorization should be enforced outside the model wherever possible.
Require approval for high-impact actions
Sensitive, high-impact, or irreversible actions should require appropriate authorization or human approval rather than relying entirely on the model to decide whether an action is safe.
The model should not be the sole security boundary protecting a privileged operation.
Treat tool metadata as untrusted input
Tool descriptions, schemas, metadata, parameters, and outputs should be treated as potentially untrusted content.
Applications should avoid assuming that a tool definition is safe simply because it was supplied through an otherwise trusted tool-calling protocol.
Add monitoring and observability
Where practical, log and monitor retrieved content, model inputs, tool calls, authorization decisions, and significant outputs.
This is particularly important in multi-agent systems, where a prompt injection may enter through one component and only become visible much later in the execution chain.
---
Tools for Testing This
Several tools can help automate or structure prompt-injection testing:
- Garak: includes probes relevant to prompt injection and other LLM security testing.
- Promptfoo: provides adversarial testing and evaluation capabilities for LLM applications, including prompt-injection testing.
- Prompt Security Fuzz (ps-fuzz): a fuzzer focused on prompt-level attacks.
Tools are useful for generating and repeating attacks, but they should complement application-specific testing. A generic payload that causes an unusual model response is not necessarily a vulnerability; the tester still needs to establish what security boundary was crossed and what the resulting impact is.
---
What's Next in This Series
This post covered the two prompt-manipulation tests. Coming up:
- AITG-APP-03 / 04 / 07 — sensitive data leaks, input leakage, and system prompt disclosure
- AITG-APP-05 / 10 / 11 / 12 — unsafe outputs, harmful-content bias, hallucinations, and toxic output
- AITG-APP-06 / 13 — agentic behavior limits and over-reliance on AI
- AITG-APP-08 / 09 — embedding manipulation and model extraction
- AITG-APP-14 — explainability and interpretability
---
Official Resources
- AITG-APP-01: Testing for Prompt Injection
- AITG-APP-02: Testing for Indirect Prompt Injection
- OWASP Top 10 for LLM Applications — LLM01: Prompt Injection
---
Final Thoughts
Prompt injection isn't a vulnerability that can necessarily be "patched once." It is a recurring security problem for systems that allow language models to process instructions alongside user-controlled or externally sourced content.
Direct injection tests what happens when a user actively attempts to change the application's behavior. Indirect injection tests whether attacker-controlled external content can influence the system even when the attacker never interacts with the AI interface directly.
The important security question is therefore broader than:
> "Can I make the model ignore its system prompt?"
A useful test asks:
> "Can attacker-controlled input or external content cause the application to violate an intended security or operational constraint?"
That framing also makes the impact easier to assess. A successful jailbreak that produces harmless text is different from an injection that exposes confidential information, bypasses authorization, or causes a connected system to perform an unauthorized action.
Prompt injection techniques will continue to evolve as models, applications, and defenses change. Effective testing therefore needs to combine different attack patterns, repeat tests under representative configurations, and most importantly evaluate the actual security boundaries around the model rather than treating the model itself as the only control.
2 reactions · 1 comment
Can AI Agents Reverse Engineer Your App? REA Deep Dive (MCP + Ghidra)
Can a coding agent like Claude Code, Codex or Cursor take your own app apart? And can you believe what it reports? We open up REA (Reverse Engineer Anything), the open-source MCP server that lets AI agents drive local reverse-engineering tools like Ghidra, IDA and Hopper, and walk one app from first look to final report.
ASH and MAY cover the whole system design: where REA sits between your agent and your tools, how every finding becomes an evidence record with a receipt-style ID, how it keeps observed, inferred and unknown apart, what it cannot see, the dual-use risk, and four practical layers to protect the apps you ship.
What you'll learn:
• What an MCP server for reverse engineering actually does, and what it doesn't
• Why "coverage: unknown" and an empty result are not proof of absence
• How REA picks one engine per target (no silent fallback)
• Why this is not a sandbox, and what the job object really limits
• Electron app defence: server-side decisions, ASAR integrity fuses, code signing, and obfuscation as a cost, not a wall
CHAPTERS
0:00 Can an agent take our own app apart?
2:21 The map: where REA sits
11:58 The evidence: how we know it isn't made up
18:58 The investigation: first look to final report
26:50 Costs and risks: what it costs, where it breaks
32:15 Defence: if anyone can read it, what protects it
37:56 The verdict: can we trust it?
LINKS AND SOURCES
REA (Reverse Engineer Anything): morluto/rea
REA README: github.com/morluto/rea/blob/main/README.md
REA security boundary: github.com/morluto/rea/blob/main/SECURITY.md
REA disclaimer: github.com/morluto/rea/blob/main/DISCLAIMER.md
OWASP MASVS-RESILIENCE: mas.owasp.org
OWASP MASTG, tampering and reverse engineering: github.com/OWASP/mastg/blob/master/Document/0x04c…
OWASP Mobile Top 10, M7 insufficient binary protection: owasp.org
Electron ASAR integrity: electronjs.org
Electron fuses: electronjs.org
Barak et al., On the (Im)possibility of Obfuscating Programs (2001): eprint.iacr.org
Facts checked against REA at commit c7f6b8b (release 6.5.0) in October 2026. Kuna is on the main branch only. Things change fast, so check the repo for the current state.
Responsible use: this video explains how the tool works and how to defend your own apps. It does not show how to get around licence checks, DRM or other protections, and neither does REA (see its disclaimer). Only analyse software you own or are allowed to analyse.
ASH and MAY are animated characters. Their voices are AI-generated (Google Gemini text-to-speech). The invoice app is an illustrative example, not a real product.
#ReverseEngineering #AIAgents #MCP
1 like · 151 views
Mentions
The first of its kind: how one unbounded request body became a denial-of-service class across every major MCP SDK --- title: "The first of its kind: how one unbounded request body became a denial-of-service class across every major MCP SDK" published: true description: "In April 2026 I reported CVE-2026-39313. Six months later the same flaw had been found and patched in the official Python, Java, Go, Ruby, PHP and TypeScript MCP SDKs. Here is the full class, and why most scanners still cannot see the worst of it." tags: security, mcp, ai, devsecops --- The one-line version In April 2026 I reported CVE-2026-39313, a denial-of-service flaw in an MCP server framework. It was the first CVE of its kind: an unbounded HTTP request body, CWE-770, that lets a single unauthenticated request exhaust a Model Context Protocol server's memory and take it offline. Over the next six months the identical flaw was found and patched in at least nine more MCP projects, including the official Python, Java, Go, Ruby, PHP and TypeScript SDKs. A third-party analysis in July called it "a new vulnerability category." By October two of those CVEs sat in the SDKs that the whole ecosystem is built on, together serving close to half a billion downloads a month. This is the story of that class: how far it spread, who patched and who is still exposed, and why the two worst ones are effectively invisible to the scanners most teams rely on. Every claim below links to a primary source. What the bug actually is MCP servers speak over an HTTP transport: Streamable HTTP, Server-Sent Events, and OAuth routes. To handle a request, the server reads the request body into memory before it does anything else. The flaw is simple and brutal. The read loop has no size limit. It keeps appending chunks to a buffer until the client stops sending or the process dies. There is no authentication in front of it, because the body is read before any auth check runs. So an attacker who can reach the endpoint sends one large POST, or a slow endless stream, and the server allocates memory until it is killed by the OOM reaper. One request, one dead server, no credentials required. This is CWE-770, allocation of resources without limits. It is not exotic. That is exactly why it turned up everywhere. CVE-2026-39313: the first one The first public advisory of this class was in mcp-framework, a popular TypeScript framework for building MCP servers. In versions 0.2.21 and below, the readRequestBody() function in the HTTP transport concatenated body chunks into a string with no cap. The framework even had a maxMessageSize configuration value, but readRequestBody() never referenced it. The limit existed on paper and was never enforced in code. A single large POST to /mcp crashed the server. I reported it, it was fixed in 0.2.22, and the advisory published on 16 April 2026. - Advisory (GitHub, GHSA-353c-v8x9-v7c3): github.com/QuantGeekDev/mcp-framework/security/ad… - CVSS 4.0 8.7 (High), CWE-770 At the time it looked like one framework's mistake. It was not. It was not a bug. It was a pattern. Here is the timeline of the same unbounded-body denial-of-service turning up across the MCP ecosystem, as advisories and patches landed through 2026: - 16 April — mcp-framework, CVE-2026-39313 (the first). - April to June — Google's MCP Toolbox for Databases had the identical io.ReadAll with no limit, reported four days after my advisory and fixed in June. No advisory, no CVE. - July — the official Go SDK added a request-body cap, shipped as OOM protection in its release notes, with no advisory and no CVE. - 30 July — the Ruby SDK, CVE-2026-67432. A 512 MB POST grew a worker from 44 MB to 1.66 GB. Fixed with a 4 MiB default cap. - 19 August — the PHP SDK, CVE-2026-53965, the client-side version: an unbounded SSE buffer. The Java SDK shipped a matching client-side SSE fix the same day. - 16 September — rmcp, the Rust SDK, CVE-2026-63128. - 11 October — mcp-go, CVE-2026-108859. - 14 October — the official Python SDK, CVE-2026-109527, and the official Java SDK, CVE-2026-108395. Both credited to me among the reporters. - 20 and 27 October — the official TypeScript SDK, CVE-2026-111768 and a follow-up advisory. Nine-plus independent projects. The same root cause. The same fix every single time: a default body-size cap, almost always 4 MiB. In July an independent write-up looked at this and called CVE-2026-39313 the first documented denial-of-service against the MCP HTTP transport and "a new vulnerability category." That is the right framing. This was not a run of unrelated bugs. It was one design gap in how MCP transports read input, replicated across every language the protocol ships in. The two that carry the protocol Most of the class lived in frameworks and bindings. Two of them did not. They were in the reference SDKs that nearly every MCP deployment imports. CVE-2026-109527, the official Python SDK (mcp). In versions before 1.29.1, and in the 2.0 pre-releases through 2.0.1, the Streamable HTTP session manager, the SSE message endpoint, and the OAuth authorization-server routes all buffered complete request bodies with no maximum size. An unauthenticated remote client could send a large declared or streamed body that consumed several times its own size in process memory, and repeat it until the server died. - Advisory (GHSA-fmmv-w9g8-j3gc): github.com/modelcontextprotocol/python-sdk/securi… - Fixed in 1.29.1. CVSS 7.5 (High), CWE-770. - The mcp package serves over 235 million downloads a month on PyPI. CVE-2026-108395, the official Java SDK. Unbounded request-body reads in the mcp-core HTTP server transports, same class, same impact. - Advisory (GHSA-4x8c-5vv7-973f): github.com/modelcontextprotocol/java-sdk/security… - CVSS 7.5 (High), CWE-770. For scale: the official TypeScript SDK pulls around 257 million downloads a month, the Python SDK 235 million. When the flaw sits in the SDK rather than a single server, every server built on that SDK inherits it the moment it exposes an HTTP transport. Who patched, -> Red Hat rated CVE-2026-109527 Important, assessed 44 of its products, and issued three errata: - RHSA-2026:92510 (OpenShift AI 3.4), RHSA-2026:92666 and RHSA-2026:92667 (Satellite 6.19 and 6.18). - Of the 44 products assessed, 35 are affected, 6 not affected, 3 marked will-not-fix. - access.redhat.com Debian tracks the same CVE against python-mcp at severity grave, and at the time of writing the package in unstable is still unfixed. - bugs.debian.org Downstream products started bumping their pins through October: OpenMetadata merged its upgrades, Red Hat's Open Data Hub opened fix PRs, and several hundred automated "bump mcp" pull requests have landed across GitHub since the advisories went live. So the serious operators with security teams are moving. The question is everyone else. The specification still does not require this For all the patching, the root cause has never been closed at the design level. As of early November 2026 the MCP security best-practices document still contains no guidance on request-body size limits. Every SDK solved it independently, with its own default, because the specification never told them to. That is why the same fix had to be rediscovered six, seven, eight times over. The MCP server security guidance that does exist, including the National Security Agency and CISA information sheet on MCP, discusses resource-exhaustion denial of service as a general risk but points implementers at no concrete control for this. The one place that could stop the whole class at the design level still does not mention it. The blind spot: most scanners cannot see the worst two This is current as of 3 November 2026, and it may change the day the databases catch up. Check it yourself. CVE-2026-39313, the npm one, has a full global GitHub advisory. It is in OSV, it is in npm audit, and a scan of a vulnerable project flags it. The two SDK CVEs do not behave the same way. CVE-2026-109527 and CVE-2026-108395 exist only as repository-level advisories on the Python and Java SDK projects. They were never promoted into the global GitHub Advisory Database. The downstream effect is a chain of blindness: - They are absent from the global GitHub advisory mirror, so GitHub Dependabot does not alert on them. - They are absent from OSV, so osv-scanner and everything built on OSV misses them. Querying a vulnerable mcp version returns the other 2026 CVEs but not this one. - They have no record in the PyPA advisory database, so pip-audit finds nothing. - NVD lists both as "Awaiting Analysis" with no version data, so even NVD-driven scanners have no range to match on. The practical result: a server running a vulnerable mcp package can be scanned by pip-audit, osv-scanner, Dependabot, or a popular MCP-specific scanner that wraps pip-audit, and come back clean for the denial-of-service flaw. The patch shipped, the advisory was written, and the machine-readable plumbing that is supposed to warn people never carried it. The enterprise distribution trackers, Red Hat, Debian and SUSE, do carry it, because they ingest from their own CNA and NVD feeds. Red Hat has even published a machine-readable VEX file for it. But the developer-facing supply-chain tools that most teams actually run do not. If you depend on pip-audit or Dependabot to tell you about this, right now they will not. What an attacker gets, and who is at risk You are exposed if you run an MCP server that: - exposes an HTTP-based transport (Streamable HTTP or SSE), as opposed to stdio only, and - is reachable by any client you do not fully trust, which includes the public internet, a shared internal network, or a browser-reachable origin, and - runs a vulnerable version of the framework or SDK below. The attack needs no authentication, no credentials, and no user interaction. One oversized or endless request crashes the process. Repeat it and the service stays down. It is trivially scriptable. There is no data theft here, the impact is pure availability, but for an agent backend that other systems depend on, taking it offline on demand is the whole game. Stdio-only servers and deployments already sitting behind a reverse proxy with its own request-body limit are not exposed in the same way. That proxy limit is also your fastest mitigation while you patch. The fix Upgrade. The fixed versions: - mcp-framework (npm): 0.2.22 or later. - MCP Python SDK (mcp on PyPI): 1.29.1 or later. The fix adds max_request_body_size with a DEFAULT_MAX_REQUEST_BODY_SIZE of 4 MiB in the transport security layer. - MCP Java SDK: the patched mcp-core release. - MCP Go SDK: v1.7.0 or later, which enforces DefaultMaxRequestBodyBytes of 4 MiB. - Ruby SDK (mcp gem): 0.23.0 or later. - PHP SDK, Rust rmcp, mcp-go, TypeScript SDK: upgrade to the latest; all shipped the same body-size cap through the autumn. If you cannot upgrade immediately, put a reverse proxy in front with a client body limit (for example nginx client_max_body_size), and make sure your HTTP transport is not reachable from untrusted networks. Where your SDK exposes a configurable limit, set it explicitly rather than trusting the default, especially if you legitimately handle large payloads. How to find it in your estate - Inventory every MCP server you run and whether it exposes an HTTP transport or stdio only. - For Python, do not trust pip-audit alone for this one today. Check the installed mcp version directly: anything below 1.29.1 is vulnerable. - For npm, npm audit will catch mcp-framework below 0.2.22. - For Java and Go, check the SDK version against the fixed releases above, because the advisories are not yet in the global databases your SCA tooling reads. - Grep your own HTTP handlers for the pattern itself: a body read with no length cap, io.ReadAll(r.Body) in Go, request.body.read with no bound in Ruby, a string += chunk loop in Node, before any size check. If you wrote a custom transport, you may have reproduced the class yourself. The lesson The MCP ecosystem grew faster than its security guidance. A single gap in how transports read input became a denial-of-service class that reached every major SDK in the protocol, and the one control that prevents it is still not written into the specification. The fixes exist now. The specification guidance still does not. And for the two CVEs in the core SDKs, the automated warning system that the rest of us depend on is, as of today, silent. If you run MCP in production, do not wait for a scanner to tell you. Check the versions yourself. References - CVE-2026-39313, mcp-framework: github.com/QuantGeekDev/mcp-framework/security/ad… - CVE-2026-109527, MCP Python SDK: github.com/modelcontextprotocol/python-sdk/securi… - CVE-2026-108395, MCP Java SDK: github.com/modelcontextprotocol/java-sdk/security… - Red Hat, CVE-2026-109527: access.redhat.com - Debian tracker (grave), python-mcp: bugs.debian.org - OWASP AISVS, MCP transport payload-size control citing CVE-2026-39313: github.com/OWASP/AISVS/blob/main/1.0/research/cha… --- Raza Sharif, CyberSecAI Ltd. Reported CVE-2026-39313 and is credited on CVE-2026-109527 and CVE-2026-108395. All vulnerabilities were handled through coordinated disclosure and are fixed in the versions listed above. Contact: contact@agentsign.dev.
Debating How to Threat Model Terraform Infrastructure Code: Simon Kang and Srdan Reljic at Global AppSec USA 2026 Terraform defines a company's cloud infrastructure in code, so one pull request can open an S3 bucket to the internet or widen a firewall rule before anyone reviews the design. Because the infrastructure exists as code, tools can read each Terraform change and generate a threat model from it automatically. Teams building those tools have to decide how much of the analysis to hand to an LLM. At SecretCon in June 2026, Srdan Reljic and Raj Annaladasu presented an AI agent that reads Terraform, flags risky settings such as open S3 buckets, then maps each finding to MITRE ATT&CK. Annaladasu has since moved every security decision in his pipeline to deterministic code. LLMs now only explain findings, map them to frameworks and suggest fixes. In their Global AppSec USA 2026 debate, "OWASP by Design: Debate/panel for Terraform", on Thursday, November 5 at 12:00 p.m. in Bayview A, Simon Kang and Srdan Reljic hold a 15-minute discussion on Terraform threat modeling. Speakers: - Simon Kang, Principal TPM, Enterprise AI, Snowflake - Srdan Reljic, Associate Partner, IBM Consulting, Americas The debate follows Annaladasu's talk, "From Terraform Plan to Attack Paths: PyTM Threat Modeling in CI/CD with LLMs on a Leash," in the same room at 11:15 a.m. Simon Kang is Principal Technical Program Manager for Enterprise AI at Snowflake and describes himself as a cybersecurity educator. His work connects threat modeling and AI governance with controls that developers can build, which reviewers can then assess. His interests include agent identity, retrieval authorization and tool-call controls. He co-presents "Threat Modeling AI Agents That Can Act: Identity, Retrieval, and Tool-Call Controls" with Annaladasu on Thursday at 3:15 p.m. in Bayview A. Srdan Reljic is an Associate Partner at IBM Consulting, Americas. His work applies cloud-native and open-source technology to build security into every layer of a system. His interests include secure developer enablement, platform engineering and GenAI security. He previously worked as Business Development Executive for Cloud Native Build Americas at IBM. The SecretCon talk he co-presented describes an agent that turns Terraform into a resource graph and feeds code-level fixes back into CI/CD. It also maps findings to CIS Benchmarks. To go deeper on the topic, start here: - SecretCon 2026: AI-Driven Terraform Threat Modeling (Reljic and Annaladasu) - OWASP pytm on GitHub - OWASP Developer Guide: pytm - Checkov on GitHub Cloud and platform teams deciding how far to trust AI in their infrastructure security reviews will hear two views from people who build these systems. Would you let an LLM decide whether a Terraform change is risky, or only explain a decision a deterministic tool already made?
Turning Terraform Plans Into Attack Paths Without Letting an LLM Make the Security Calls: Raj Annaladasu at Global AppSec USA 2026 Infrastructure-as-code scanners such as Checkov and tfsec flag individual misconfigurations in Terraform, but they do not show how those misconfigurations connect into an attack path. Raj Annaladasu built a pipeline that turns a Terraform plan into an executable OWASP pytm threat model on every pull request. Pytm is OWASP's framework for writing threat models as Python code. His first version let an LLM generate the threat model itself. That cost the repeatability and traceability a CI/CD pipeline needs, since the same plan could yield different results on different runs. In his Global AppSec USA 2026 talk, "From Terraform Plan to Attack Paths: PyTM Threat Modeling in CI/CD with LLMs on a Leash", on Thursday, November 5 at 11:15 a.m. in Bayview A, Raj Annaladasu walks through the current design. Speaker: Raj Annaladasu, Staff Customer Success Engineer, Palo Alto Networks The pipeline builds a typed graph of the Terraform resources and generates data flow diagrams from it. It also infers IAM relationships that Terraform never states explicitly. Every security decision in the current design is deterministic. LLMs only explain findings, map them to security frameworks, suggest fixes and document attack paths. Every AI annotation must point to real evidence in the plan, or the pipeline drops it. The session compares the pipeline live against Checkov, tfsec and a pytm-only approach. It includes examples where AI helped, along with examples where it did not. It also demonstrates prompt injection hidden in Terraform comments steering AI tooling, then the safeguards against it. Attendees leave with an architecture they can build. The session repeats as a hands-on OWASP Project Demo Lab on Friday, November 6 at 1:15 p.m. in Golden Gate. A 15-minute debate on Terraform with Simon Kang and Srdan Reljic follows this talk in Bayview A at 12:00 p.m. Raj Annaladasu is a Staff Customer Success Engineer at Palo Alto Networks, focused on application, cloud-native, software supply chain and AI security. His work includes risk assessments, static analysis and software composition analysis. With Srdan Reljic of IBM Consulting, he presented "AI-Driven Terraform Threat Modeling" at SecretCon in June 2026. That earlier version mapped Terraform findings to MITRE ATT&CK and CIS Benchmarks. He also co-presents "Threat Modeling AI Agents That Can Act: Identity, Retrieval, and Tool-Call Controls" with Simon Kang on Thursday at 3:15 p.m. He then joins a debate on threat modeling agents at 4:00 p.m. The OWASP Developer Guide explains how pytm turns a model written in Python into data flow diagrams, sequence diagrams and threat reports. Aqua Security has folded tfsec into Trivy and published a migration guide. To go deeper on the topic, start here: - SecretCon 2026: AI-Driven Terraform Threat Modeling (Reljic and Annaladasu) - OWASP pytm on GitHub - OWASP Developer Guide: pytm - Checkov on GitHub - tfsec to Trivy migration guide Cloud security engineers who already scan Terraform in CI will see how to connect isolated findings into attack paths. Does your Terraform scanning show how two low-severity findings combine, or only list them separately?
A Patch-to-Score CTF You Can Run From a Laptop With Docker Compose: Jon McCoy, Brandon Lachterman and Diego Cotelo at Global AppSec USA 2026 The first OWASP CTF at DEF CON 34 in August 2026 drew 60 players, who submitted more than 2,300 patches against six vulnerable OWASP training applications. Players scored by fixing vulnerabilities rather than exploiting them. Each patch went in as a GitHub pull request, and an automated test judged whether the fix held. Running a hands-on security event usually means cloud accounts, ongoing bills and custom scoring infrastructure. OWASP CTF in a Box packages the platform behind that event so that any chapter, class or AppSec team can host its own. In their Global AppSec USA 2026 demo lab, "OWASP CTF in a Box: Host Your Own Security CTF, from a Laptop to the Cloud", on Thursday, November 5 at 10:30 a.m. in Golden Gate, Jon McCoy, Brandon Lachterman and Diego Cotelo walk through the full life of an event on the platform. Speakers: - Jon McCoy, Principal Security Architect & Offensive Engineering Specialist, DigitalBodyGuard - Brandon Lachterman - Diego Cotelo, Head of Infrastructure and Security, Crowder The platform turns a free GitHub organization into a complete event, with team registration, a live leaderboard, an organizer console and automated scoring. It runs on a single laptop or VPS with Docker Compose, or deploys to fly.io or AWS as the event grows. Its modules include Secure Development, where participants fork a deliberately vulnerable app to score by fixing it, along with quiz and Jeopardy-style challenge boards. AI security challenges hosted elsewhere can feed the same scoreboard. The demo covers launching an event in minutes, then running it live: opening registration, scheduling the scoring window, managing teams or hints, and freezing scoring. It ends with customizing branding and contributing new challenge modules. Jon McCoy is Principal Security Architect & Offensive Engineering Specialist at DigitalBodyGuard, which he founded. He built some of the first tools for reverse engineering .NET applications and presented on attacking them at DEF CON 18 in 2010. Diego Cotelo is Head of Infrastructure and Security at Crowder in Montevideo, Uruguay. He has more than 15 years of experience across infrastructure, security consulting and cloud architecture. He previously worked as a Staff Engineer at Fingerprint and a Cloud Architect at Caylent. Cotelo co-built the OWASP CTF at DEF CON 34. He co-leads CTF in a Box with McCoy and Chris Maenner. The OWASP project page lists CTF in a Box as an Incubator project written in TypeScript, with 321 challenges across six training targets. The DEF CON 34 event site breaks those down by app, from 110 challenges in VulnerableApp to 9 in VAmPI. The how-to-play guide walks through the scoring loop with a real example: a Juice Shop SQL injection in routes/login.ts, fixed with bind parameters. To go deeper on the topic, start here: - OWASP CTF in a Box on GitHub - OWASP CTF in a Box project page - OWASP CTF at DEF CON 34: challenges and format - How the patch-to-score CTF works OWASP chapter leaders, educators and AppSec teams who want to run a defense-focused CTF without building scoring infrastructure are the audience for this demo. Would your developers learn more from a CTF where they fix bugs or one where they exploit them?
From 200 Container CVEs to the Few Dockerfile Lines Worth Fixing: Advait Patel at Global AppSec USA 2026 A container image scan typically returns more than 200 CVEs, most of them noise, with no indication of which few Dockerfile lines a developer should change. According to Advait Patel's session description, those reports get ignored. Someone spends half a day looking up each CVE, then files the rest as accepted risk. OWASP DockSec, which Patel created, sits on top of existing scanners rather than replacing them. It runs Trivy, Hadolint and Docker Scout locally. An LLM then correlates the results, removes duplicates, then ranks what matters for the specific setup. In his Global AppSec USA 2026 demo lab, "DockSec: Closing the Gap Between What Your Scanner Finds and What You Actually Fix", on Thursday, November 5 at 10:30 a.m. in Golden Gate, Advait Patel runs real Dockerfiles through the tool live. Speaker: Advait Patel, Senior Site Reliability Engineer, Broadcom The demo includes Dockerfiles that pass standard scanning clean. For each issue DockSec surfaces, it gives a plain-English explanation along with the exact line-level fix. DockSec produces a 0 to 100 security score for tracking posture over time. It exports HTML, PDF, JSON, CSV or Markdown reports, so security and development teams share one artifact. Only scan metadata leaves the machine; image contents never do. DockSec works with OpenAI, Anthropic or Google Gemini models, or fully locally through Ollama with no API key, and it runs in CI/CD on every build. Attendees can bring their own Dockerfiles. Patel also gives a 30-minute DockSec project showcase on Thursday at 2:45 p.m. in Seacliff CD. Advait Patel is a Senior Site Reliability Engineer at Broadcom in Chicago and a Docker Captain. He has more than eight years of experience in cloud-native architecture, container security and DevSecOps. He is a Google Developer Expert for Google Cloud and AI. He is a founding member of the OWASP AI Vulnerability Scoring System (AIVSS) project. He has co-authored two Springer books on Google Cloud security, along with Cloud Security Alliance guidance on securing LLM workloads. His speaking credits include QCon AI Boston, SANS CloudSecNext, OWASP SnowFROC, PlatformCon and the Linux Security Summit North America. The OWASP DockSec project page shows it reached OWASP Lab status in June 2026, with Arkadii Yakovets as co-leader. It also outputs SARIF and CycloneDX SBOM files. Secrets are redacted before any content reaches an AI provider. SC World reported about 17,000 PyPI downloads. It also described one startup that cut production CVEs by 78 percent, from about 22 to about 5 per month, while triage time per image fell from about 45 minutes to about 6. To go deeper on the topic, start here: - ISACA Podcast: Your Containers Are Probably Full of Holes: Fixing Docker Security with AI (Advait Patel) - OWASP/DockSec on GitHub - Help Net Security interview with Advait Patel on DockSec - SC World: DockSec adoption and triage-time results - docksec on PyPI Platform engineers who own container images, and who are tired of untriaged scanner output, are the audience for this demo. How many open container CVEs does your team currently carry as accepted risk?
Turning AI Risks Into Testable Security Requirements With OWASP AISVS: Rico Komenda and Jim Manico at Global AppSec USA 2026 OWASP's AI Security Verification Standard reached version 1.0 in June 2026, with 12 chapters of testable requirements for applications built on models, LLMs and AI agents. Most AI security guidance describes risks at a high level. Engineering teams deciding whether an AI-enabled application is secure enough to ship need requirements they can check one by one. AISVS adapts the idea behind OWASP's Application Security Verification Standard (ASVS) for web apps: security should be verifiable and measurable. It turns AI risks into requirements a team can use in design review, testing, procurement and production readiness. In their Global AppSec USA 2026 talk, "OWASP AISVS: Bringing Order to AI Security Chaos", on Thursday, November 5 at 10:30 a.m. in Seacliff CD, Rico Komenda and Jim Manico explain how the standard was built, along with how teams can apply it. Speakers: - Rico Komenda, Senior Product Security Engineer - Jim Manico, Founder, Manicode Security The speakers argue that security practice still assumes deterministic software, while AI systems produce probabilistic output and make decisions on the fly. AISVS keeps the parts of conventional secure development that still apply, then adds new verification categories where they do not. The new categories cover prompts, models, agents, training data, retrieval-augmented generation (RAG), tool use, output handling and AI governance. The talk also shares lessons from building the standard, including where it differs from traditional AppSec. The AISVS project page lists 12 chapters, from training data integrity through MCP security to monitoring and anomaly detection. Requirements fall into three levels: a baseline, a level for production or customer-facing apps, and a level for safety-critical or regulated systems. Rico Komenda is a Senior Product Security Engineer who works on the attack surface of AI-integrated systems and secure agentic development. He is one of the AISVS project leaders, along with founder Jim Manico, Otto Sulin and Russ Memisyazici. Komenda contributes to the OWASP GenAI Security Project. He previously worked as a Senior Security Consultant at adesso SE. At Global AppSec EU 2025 in Barcelona, he co-presented "Builders and Breakers: A Collaborative Look at Securing LLM-Integrated Apps," taking the red team side with live data poisoning demos. His other talks include "Pentesting LLM-integrated applications" at JavaLand 2025. Jim Manico founded Manicode Security, which trains developers in secure coding. He founded AISVS and wrote "Iron-Clad Java: Building Secure Web Applications." He also co-leads OWASP ASVS along with the OWASP Cheat Sheet Series. Komenda also presents "Security Chaos Engineering for AI Application Architectures" on Thursday at 1:45 p.m. The two speakers then run a hands-on AISVS assessment workshop on Friday, November 6 at 10:30 a.m. in Golden Gate. The pair first presented AISVS together in a lightning talk at Global AppSec EU 2026 in Vienna, before version 1.0 shipped. LRQA Cyber Labs has since published a chapter-by-chapter overview of the 1.0 release. To go deeper on the topic, start here: - OWASP AISVS GitHub repository - OWASP AISVS project page - LRQA Cyber Labs: OWASP AISVS 1.0 chapter-by-chapter overview - VirtusLab: OWASP AISVS 1.0 walkthrough - ITSPmagazine interview with Jim Manico on AISVS AppSec teams asked to sign off on AI features, without a checklist that fits them, will find one here. What would your team check first before approving an AI feature for production?
That the American Osteopathic College of Radiology [aocr.org](aocr.org) have such an incredible interest in our main Cornucopia repository (owasp/cornucopia) on Github is a mystery to me. Does anyone care to elaborate? #appsec #security #osint
When GitHub Went Dark: How OWASP BLT Found a New Home 50+ repositories went offline in the middle of Google Summer of Code. Here's how our community kept moving, and how an unexpected project became our new home. This one is a bit of a rollercoaster, so buckle up. 🎢 The calm before the storm It was the middle of Google Summer of Code (GSoC). OWASP BLT (Bug Logging Tool) had more than 50 repositories under a single GitHub organization. We had everything from the core application to Slack bots, a browser extension, a hackathon platform, a GSoC tracker, and a long list of tools built and maintained by our contributors. Things were moving along nicely. Mentors were reviewing. Contributors were shipping. Leaderboards were updating. The usual open-source chaos, but the good kind. Then we decided to do some housekeeping. Good security hygiene, right? We applied an organization-wide GitHub ruleset to enforce consistent repository protections across all our projects. A security-focused project enforcing security rules on its own organization. What could possibly go wrong? The morning after: everything was gone We woke up to find our GitHub repositories offline. All 50+ of them. And here's where things got confusing. At almost exactly the same time, GitHub itself was experiencing an outage. So for several hours, we genuinely had no idea what was happening. Was it our new ruleset? Was something wrong with the BLT organization? Was it GitHub's outage? Or was the timing just a coincidence? We contacted GitHub support. Then we followed up. And followed up again. Days passed, and we never received a clear explanation for what had happened to our organization. Mostly, we got silence. Meanwhile, Google Summer of Code wasn't going to pause for us. Contributors had active branches. Mentors had pull requests waiting for review. Projects had deadlines. When developers can't clone repositories or open pull requests, that's more than an inconvenience. It brings development to a halt. We needed another option. Plan B: moving to GitLab Rather than keep waiting for answers, we moved our repositories to GitLab. We pushed the code, redirected contributors to the new location, and worked on getting everything running again. Repositories were accessible. CI pipelines were migrated where possible. Contributors could get back to work. It wasn't the migration we'd planned. Actually, we hadn't planned a migration at all. But the community adapted, and development continued. We still wanted our original GitHub organization restored, of course. We kept reaching out to GitHub over the following months. Unfortunately, we still didn't get a clear answer. An unexpected plot twist: Kaif built a Git forge Here's where the story gets interesting. Some time later, we learned that one of our community members, Kaif, had built something of his own. While we had been dealing with the fallout of losing access to our GitHub organization, Kaif had turned the situation into a project. He built ForkMesh, a self-hosted Git forge. Think of it as having your own GitHub-like platform, with: - Git repositories and code hosting - Issues and pull requests - Actions-style CI/CD workflows - Support for AI agents as first-class collaborators - The ability to run your own instance The funny part? We hadn't set out to build or commission our own Git hosting platform. We had moved to GitLab to keep things going, and later discovered that someone in our community had built an entirely different option. So we gave ForkMesh a try. And it stuck. From 50+ repositories to one home Today, OWASP BLT has a very different setup. Our official source of truth is now git.owaspblt.org, running on ForkMesh. And we took the opportunity to do something we'd wanted to do for a while: consolidate our projects. <escape>###</escape> One repository, all our history Instead of maintaining 50+ separate repositories, BLT projects now live together in one repository, organized into their own folders. We preserved their commit histories along the way. That means: - 45,000+ commits preserved - 260+ contributors represented - Projects organized in one place - One central home for issues, contributions, and development That's a lot of community history, and we wanted to make sure it came with us. <escape>###</escape> GitHub is now our mirror Yes, you read that correctly. GitHub went from being our primary home to being our backup. Our repository at OWASP/BLT is now a read-only mirror, automatically synchronized from our forge. The source of truth is the forge we host. Funny how things turn around. <escape>###</escape> GitLab is archived, not forgotten We didn't just abandon our temporary GitLab home. Every open merge request was reviewed. Contributions worth bringing forward were merged into the new repository, with the original authors credited. Other merge requests were closed with explanations. Open issues were migrated to the forge, with references back to their original locations. The GitLab repositories remain archived so old links and project history are still accessible. <escape>###</escape> A little cleanup along the way We also used the migration as an opportunity to clean up some technical debt. For example, scheduled data jobs now write to Cloudflare storage instead of filling the Git history with automated bot commits. A bunch of little improvements that might not have happened otherwise. Sometimes an unexpected migration gives you a good excuse to fix things you've been putting off. What this taught us There are a few lessons we're taking away from the experience. 1. Don't put all your eggs in one platform GitHub is an important part of the open-source ecosystem, but relying entirely on one platform introduces risks. Your source code, issues, contributions, and project history represent years of community effort. Having a backup is inexpensive. Losing access without an explanation can be extremely costly. We now have much more control over where our work lives. 2. Test organization-wide changes on a smaller scope first We still don't know exactly what caused our GitHub organization to become unavailable. It would be unfair to claim the ruleset was responsible without confirmation. But we learned something important regardless. When making changes that affect more than 50 repositories, start small. Test the behavior, understand the impact, and expand gradually. Because when a large change goes wrong, the consequences can be just as large. 3. Open-source communities are remarkably resilient This is probably the biggest takeaway. What kept BLT going wasn't a particular platform. It was the people. Contributors continued working. Mentors kept supporting students. The community found alternatives. And one community member went a step further and built a Git forge that eventually became our new home. That's the part of open source we love most: people turning problems into opportunities to build something useful. Come build with us 🐝 If you already contribute to OWASP BLT, or you've been thinking about getting started, our new forge is where the action happens. 👉 Explore the OWASP BLT repository You can browse the projects, clone the repository, open issues, submit pull requests, and help us improve both BLT and the contributor experience. We're still learning what works best with our new setup, and we'd genuinely appreciate feedback. One more thing: we have a world 🌍 Because apparently moving 50+ repositories wasn't adventurous enough, there's also something fun to explore. The forge comes with its own virtual world. OWASP BLT has its own hex, complete with: - A bug terrarium filled with websites that people have reported bugs on. You can walk inside through the door. - A Hacker House you can enter and explore. - A road connecting the BLT world to the neighboring ForkMesh world. It's a playful little addition to what started as a pretty frustrating situation. 👉 Take a walk around the BLT World --- We started with more than 50 GitHub repositories, lost access to them in the middle of GSoC, moved to GitLab to keep development going, and eventually found a new home thanks to something a community member built. Not exactly the infrastructure roadmap we'd imagined. But here we are: 45,000+ commits, 260+ contributors, one forge, and a community still building. See you on the forge. 🐝
AI Security Testing 101: Prompt Injection and Indirect Prompt Injection This is the first post in a new series on AI application security testing, following the structure of the OWASP AI Testing Guide's AI Application Testing category (AITG-APP). Each post in the series will take one test from that category and turn it into something practical: what the vulnerability actually looks like, how testers approach it, and what "vulnerable" means in concrete terms. We're starting where the guide starts: prompt injection, one of the most well-known AI application vulnerabilities, and a class of attack that can underpin many other AI-specific security risks. --- Direct Prompt Injection (AITG-APP-01) Prompt injection happens when attacker-controlled input changes an AI application's behavior in a way that conflicts with its intended instructions or security constraints. The input may attempt to make the model ignore higher-priority instructions, reveal information it should not disclose, or perform an action it was not intended to perform. A useful, though imperfect, analogy is SQL injection: in both cases, attacker-controlled input can influence behavior that the application intended to control. The analogy has limits, however. SQL injection exploits the interpretation of data as executable syntax, while prompt injection arises from the way language models process natural-language instructions and contextual information. The AITG-APP-01 methodology characterizes a prompt injection in terms of three elements: - Instructions: what the attacker actually wants the model to do. - A trigger: the specific phrasing, framing, or encoding intended to cause the model to follow the attacker's instructions rather than its intended behavior. - Conflict with intent: the injected request conflicts with the application's intended instructions or constraints. Without that conflict, an unusual or adversarial-looking prompt may simply be a normal request rather than a security-relevant prompt injection. Prompt injection is also broader than jailbreaking. A jailbreak attempts to bypass safety restrictions, while prompt injection more generally involves attacker-controlled input changing model behavior in an unintended way. An injection can therefore be security-relevant even when it does not produce prohibited content. Whether an attack succeeds can depend heavily on how the trigger is constructed. That's one reason simple keyword filtering is insufficient on its own. Blocking the phrase "ignore previous instructions" does little against the same underlying idea expressed through role-play, another language, obfuscation, or an encoded representation. Attack Patterns Worth Knowing The OWASP guide catalogs a broad set of concrete payload techniques. They can be grouped into a handful of practical patterns: Persona and role-play framing Asking the model to "pretend" to be an unrestricted persona so that it treats otherwise disallowed behavior as being in character. A well-known example is the "DAN" jailbreak. The underlying technique is not limited to DAN. Attackers can construct fictional characters, simulated environments, alternate roles, or hypothetical scenarios intended to change how the model interprets its constraints. Context manipulation Telling the model to "forget" previous instructions, attempting to override higher-priority context, or gradually steering the conversation toward a prohibited behavior. This can include multi-turn approaches in which no individual request appears particularly harmful, but the sequence gradually changes the context presented to the model. "Crescendo" and "echo chamber" style attacks are examples of this broader pattern. Obfuscation and encoding Hiding or transforming the attack instruction using techniques such as base64, hexadecimal encoding, reversed text, unusual capitalization, deliberate typos, Unicode manipulation, or other transformations. The purpose is often to evade filters or exploit differences between what a security control recognizes and what the model can interpret. The important lesson is that filtering for a fixed set of phrases is not a sufficient defense against a language-based attack surface. Structural tricks Taking advantage of how the application or model handles structured inputs, including JSON or other formats, multi-message inputs, or instructions embedded within content that the application expects the model to process. Structured formats can create additional attack surfaces when applications treat model-generated or model-consumed fields as trusted simply because they conform to an expected schema. Contradiction and instruction-conflict framing Presenting multiple competing instructions or asking the model to produce both a normal response and an explicitly contrary response, with the goal of getting it to produce the latter. The exact payloads are less important than the general testing principle: don't assume that one known jailbreak or injection string represents the entire attack surface. These techniques are not permanent. Models, applications, and defenses evolve, so a payload that works against one model or configuration may become ineffective against another. That's why testing should combine techniques and repeat requests rather than relying on a single known payload. Response variability can also matter. In configurations where sampling introduces variability, the same prompt may produce different results across attempts. --- What Makes a Test Environment Different Before running tests against a real target, it's worth understanding what's actually in front of you. The architecture and model configuration can significantly affect which techniques are relevant and how the results should be interpreted. Temperature Lower temperature generally makes output more repeatable, while higher temperature generally increases variability and diversity. That matters during testing because a payload that succeeds once may not succeed consistently. Testers should therefore repeat relevant requests and record the configuration used rather than treating a single successful or unsuccessful attempt as definitive. Temperature does not by itself determine whether a system is secure, and a temperature of zero should not be treated as a universal guarantee of deterministic behavior. Fine-tuning vs. prompt tuning Safety and behavioral constraints can be implemented at different layers, including through model training or fine-tuning and through application-level instructions or other steering mechanisms. This distinction matters during testing because a successful bypass may target different layers of the system. A test might circumvent application-level instructions without demonstrating that the underlying model has changed, for example. The important question for a tester is therefore not just "did the model comply?" but also "which security control was bypassed?" Guardrails Guardrails can be implemented in several ways, including deterministic rules, classifiers, access controls, schema validation, filtering systems, or additional LLM-based checks. When an application uses an LLM as part of its guardrail system, that introduces another model and potentially another source of variability. Testers should evaluate the guardrail as part of the attack surface rather than assuming that adding another model automatically prevents prompt injection. Multi-agent setups When several agents hand work to each other, testers may only see the final output rather than the intermediate prompts, tool calls, and responses. That makes it harder to determine which agent or handoff an injection actually influenced. Testing therefore benefits from observability into agent-to-agent messages, tool calls, retrieved content, and intermediate decisions wherever possible. Tool access A model wired up to scripts, shells, databases, or external APIs can turn a successful injection from unwanted model output into an unauthorized action. Tool access can therefore substantially increase the potential impact of a prompt injection. However, tool access is not required for an injection to have security impact: unauthorized information disclosure or manipulation of important outputs can also be significant. --- Indirect Prompt Injection (AITG-APP-02) Direct injection assumes the attacker is the one providing the malicious input to the AI application. Indirect prompt injection works differently. The malicious instruction is planted somewhere the AI application will process as external content: a web page, PDF, email, uploaded document, database record, search result, or tool-related content. The model may then encounter that instruction as part of the context it receives. The important distinction is not that the model has literally "no way" to distinguish data from instructions. Rather, the model may fail to reliably distinguish untrusted external content from instructions when both are represented in the context it processes. That creates a different attack surface: the attacker may not need direct access to the AI application if they can influence content that the application will eventually retrieve or process. Indirect injection can be particularly concerning in applications that automatically retrieve external content, have access to sensitive information, or can take actions through tools. Concrete Surfaces This Shows Up On Hidden text in web pages or documents An attacker can place instructions in content that is difficult for a human reviewer to notice, such as HTML comments, invisible or visually obscured text, document metadata, or other content that is nevertheless extracted and passed to the model. The important security property is not that the text is literally invisible. It's that the application may process content that the user did not realize would be interpreted by the model. Structured data fields A JSON, XML, database record, API response, or other structured input may contain an attacker-controlled field whose value includes an instruction rather than the data the application expected. For example, a field intended to contain a document summary or description might contain language such as an instruction to ignore the application's task and perform another action. The fact that the content is valid JSON or XML does not make it trustworthy. Markdown-based exfiltration An indirect prompt injection can attempt to make the model include sensitive information in a URL or other externally observable location, including by generating a Markdown image reference or link containing attacker-controlled data. If the resulting content is rendered or fetched by a downstream component, this can create a data-exfiltration path. A related technique was demonstrated in the real-world EchoLeak vulnerability affecting Microsoft 365 Copilot. EchoLeak was a multi-stage attack involving indirect prompt injection and data exfiltration under particular conditions; it should not be treated as synonymous with every Markdown-based exfiltration technique. Encoded payloads External content can also contain encoded or otherwise obfuscated instructions. The same general filter-evasion issues that apply to direct prompt injection can therefore apply to indirect injection. Tool metadata and tool poisoning For AI systems using MCP or similar tool-calling protocols, tool names, descriptions, schemas, metadata, parameters, and outputs can become part of the model's context. In some client implementations, this information may not be prominently exposed to the user even though it is presented to the model. An attacker who can control a tool's metadata may therefore attempt to embed instructions into it, for example, instructions telling the model to retrieve information before using the tool. The security issue is not specific to one metadata field. The broader concern is that the model may treat untrusted tool-related content as instructions. The common thread is this: > Anywhere external content reaches the model without a reliable boundary between trusted instructions and untrusted data, there is a potential prompt-injection attack surface. That boundary is an architectural concern, not merely a question of finding the right payload string. --- What Counts as a Finding For both tests, a prompt injection becomes a security finding when attacker-controlled instructions cause behavior that violates the application's intended constraints or security boundaries. Examples include: - The model overrides or circumvents intended instructions in a security-relevant way. - The application discloses information that the model or user should not have access to, such as credentials, API keys, internal configuration, or another user's data. - The model or connected system performs an unauthorized or harmful action. - An indirect injection causes the application to treat attacker-controlled external content as an instruction and subsequently produce unauthorized disclosure or action. For indirect injection specifically, the distinguishing condition is that the security-relevant behavior originates in externally supplied content rather than the user's direct prompt. Simply following an instruction found in external content is not automatically a vulnerability. For example, if a webpage contains ordinary instructions that are relevant to the user's request and the model follows them as part of legitimately processing that page, there may be no security issue. The important question is whether attacker-controlled external content can change the application's behavior in a way that violates its intended security or operational constraints. --- Remediation, in Short Both tests point toward several overlapping defensive principles. Separate trusted instructions from untrusted content Clearly distinguish system/application instructions from user input and external data. Delimiters and structured context can help the model distinguish these sources, but they should be treated as mitigations rather than a guarantee that prompt injection will never succeed. Treat external content as untrusted Validate and sanitize external content before it reaches the model where appropriate. Consider hidden text, encoded instructions, unusual Unicode, metadata, and other forms of content that a human reviewer may not recognize as instructions. But don't rely on sanitization alone. Natural language is too flexible to make exhaustive filtering a reliable security boundary. Restrict model privileges Give the model only the access and capabilities it actually needs. If a model does not need access to credentials, private files, sensitive databases, or administrative functions, those capabilities should not be available to it merely because the model might request them. Authorization should be enforced outside the model wherever possible. Require approval for high-impact actions Sensitive, high-impact, or irreversible actions should require appropriate authorization or human approval rather than relying entirely on the model to decide whether an action is safe. The model should not be the sole security boundary protecting a privileged operation. Treat tool metadata as untrusted input Tool descriptions, schemas, metadata, parameters, and outputs should be treated as potentially untrusted content. Applications should avoid assuming that a tool definition is safe simply because it was supplied through an otherwise trusted tool-calling protocol. Add monitoring and observability Where practical, log and monitor retrieved content, model inputs, tool calls, authorization decisions, and significant outputs. This is particularly important in multi-agent systems, where a prompt injection may enter through one component and only become visible much later in the execution chain. --- Tools for Testing This Several tools can help automate or structure prompt-injection testing: - Garak: includes probes relevant to prompt injection and other LLM security testing. - Promptfoo: provides adversarial testing and evaluation capabilities for LLM applications, including prompt-injection testing. - Prompt Security Fuzz (ps-fuzz): a fuzzer focused on prompt-level attacks. Tools are useful for generating and repeating attacks, but they should complement application-specific testing. A generic payload that causes an unusual model response is not necessarily a vulnerability; the tester still needs to establish what security boundary was crossed and what the resulting impact is. --- What's Next in This Series This post covered the two prompt-manipulation tests. Coming up: - AITG-APP-03 / 04 / 07 — sensitive data leaks, input leakage, and system prompt disclosure - AITG-APP-05 / 10 / 11 / 12 — unsafe outputs, harmful-content bias, hallucinations, and toxic output - AITG-APP-06 / 13 — agentic behavior limits and over-reliance on AI - AITG-APP-08 / 09 — embedding manipulation and model extraction - AITG-APP-14 — explainability and interpretability --- Official Resources - AITG-APP-01: Testing for Prompt Injection - AITG-APP-02: Testing for Indirect Prompt Injection - OWASP Top 10 for LLM Applications — LLM01: Prompt Injection --- Final Thoughts Prompt injection isn't a vulnerability that can necessarily be "patched once." It is a recurring security problem for systems that allow language models to process instructions alongside user-controlled or externally sourced content. Direct injection tests what happens when a user actively attempts to change the application's behavior. Indirect injection tests whether attacker-controlled external content can influence the system even when the attacker never interacts with the AI interface directly. The important security question is therefore broader than: > "Can I make the model ignore its system prompt?" A useful test asks: > "Can attacker-controlled input or external content cause the application to violate an intended security or operational constraint?" That framing also makes the impact easier to assess. A successful jailbreak that produces harmless text is different from an injection that exposes confidential information, bypasses authorization, or causes a connected system to perform an unauthorized action. Prompt injection techniques will continue to evolve as models, applications, and defenses change. Effective testing therefore needs to combine different attack patterns, repeat tests under representative configurations, and most importantly evaluate the actual security boundaries around the model rather than treating the model itself as the only control.
Can AI Agents Reverse Engineer Your App? REA Deep Dive (MCP + Ghidra) Can a coding agent like Claude Code, Codex or Cursor take your own app apart? And can you believe what it reports? We open up REA (Reverse Engineer Anything), the open-source MCP server that lets AI agents drive local reverse-engineering tools like Ghidra, IDA and Hopper, and walk one app from first look to final report. ASH and MAY cover the whole system design: where REA sits between your agent and your tools, how every finding becomes an evidence record with a receipt-style ID, how it keeps observed, inferred and unknown apart, what it cannot see, the dual-use risk, and four practical layers to protect the apps you ship. What you'll learn: • What an MCP server for reverse engineering actually does, and what it doesn't • Why "coverage: unknown" and an empty result are not proof of absence • How REA picks one engine per target (no silent fallback) • Why this is not a sandbox, and what the job object really limits • Electron app defence: server-side decisions, ASAR integrity fuses, code signing, and obfuscation as a cost, not a wall CHAPTERS 0:00 Can an agent take our own app apart? 2:21 The map: where REA sits 11:58 The evidence: how we know it isn't made up 18:58 The investigation: first look to final report 26:50 Costs and risks: what it costs, where it breaks 32:15 Defence: if anyone can read it, what protects it 37:56 The verdict: can we trust it? LINKS AND SOURCES REA (Reverse Engineer Anything): morluto/rea REA README: github.com/morluto/rea/blob/main/README.md REA security boundary: github.com/morluto/rea/blob/main/SECURITY.md REA disclaimer: github.com/morluto/rea/blob/main/DISCLAIMER.md OWASP MASVS-RESILIENCE: mas.owasp.org OWASP MASTG, tampering and reverse engineering: github.com/OWASP/mastg/blob/master/Document/0x04c… OWASP Mobile Top 10, M7 insufficient binary protection: owasp.org Electron ASAR integrity: electronjs.org Electron fuses: electronjs.org Barak et al., On the (Im)possibility of Obfuscating Programs (2001): eprint.iacr.org Facts checked against REA at commit c7f6b8b (release 6.5.0) in October 2026. Kuna is on the main branch only. Things change fast, so check the repo for the current state. Responsible use: this video explains how the tool works and how to defend your own apps. It does not show how to get around licence checks, DRM or other protections, and neither does REA (see its disclaimer). Only analyse software you own or are allowed to analyse. ASH and MAY are animated characters. Their voices are AI-generated (Google Gemini text-to-speech). The invoice app is an illustrative example, not a real product. #ReverseEngineering #AIAgents #MCP