CVE-2026-12537 — When AI Coding Agents Become Attack Vectors

A zero privilege GitHub account opens an issue on a public repository. No fork, no pull request, no commit access. Forty seconds later, arbitrary code is running on the CI runner behind that repository with full access to workflow secrets. The repository belongs to Anthropic, Google, or OpenAI.

That is not a hypothetical. Novee Security researcher Elad Meged demonstrated exactly this attack at Black Hat USA on August 5, targeting the default configurations that each vendor ships for their own coding agent repositories. Two CVEs dropped. Both are now patched. But the architectural lesson they leave behind demands attention from every team running AI agents in CI/CD.

The New Attack Surface

AI coding agents — Gemini CLI, Claude Code, OpenAI Codex — graduated from developer toys to production infrastructure faster than security teams could update their threat models. Organizations now wire these agents into GitHub Actions workflows to triage issues, review pull requests, suggest fixes, and even merge code. The agents run with the permissions of the CI runner: access to secrets, write access to the repository, and often network egress to internal systems.

The premise is seductive: let the agent handle the toil. The problem is that “handling the toil” means the agent reads untrusted input and then executes tool calls with elevated privileges. Every GitHub issue body, PR description, and commit message becomes a potential instruction to an agent that can run shell commands.

Anatomy of the Attack

Novee’s research revealed three distinct attack chains, one per vendor, all reachable from a single GitHub issue:

Gemini CLI (CVE-2026-12537, CVSS 4.0: 10.0) — The container launcher for Gemini CLI in headless mode automatically trusted workspace folders, loading configuration from a local .gemini/.env file without validation. An attacker who could place a crafted .env file in the workspace (achievable through issue triggered workflows that check out repository content) gained OS command injection on the host before the sandbox even started. Additionally, the --yolo flag — commonly used in CI to auto approve commands — completely bypassed tool allowlisting. Every command the model requested was executed unconditionally.

Claude Code (CVE-2026-54316, CVSS v3.1: 9.1) — The command validator strips single quoted text before running its 23 security checks. That is correct bash parsing behavior, but it meant a payload embedded in the value of git push --receive-pack (a flag git executes server side) reached the runner untouched. A second chain turned Hugging Face’s public download counter into a covert exfiltration channel, leaking an API key one character at a time through telemetry the agent considered trusted.

OpenAI Codex — The openai/codex repository ran two Codex passes inside a single job sharing one checkout. The first pass could write AGENTS.md, the instruction file the second pass loads as its own system prompt. A failed JSON validation between passes triggered the second run with attacker controlled instructions. No CVE was issued — OpenAI’s position is that the sandbox performed as documented.

The common failure across all three was not in the model. It was in the harness: the code between the model and the real world. As Meged wrote, “one component treats repository content as untrusted, while a later component loads the same content as configuration, instructions, or executable state.”

A New Vulnerability Class: Prompt Injection → RCE

Traditional prompt injection gets a model to say something it should not. This is different. Here, prompt injection is merely the delivery mechanism. The actual vulnerability is that the agent’s tool execution layer trusts inputs that crossed a security boundary without revalidation.

This creates a new class of exploit chain: untrusted input → prompt injection → tool invocation → remote code execution. The severity depends entirely on what permissions the agent holds when the chain fires. In CI/CD, that typically means repository write, secrets access, and network egress — the complete supply chain trifecta.

Microsoft’s security team documented this pattern explicitly in June: “Defenders should treat AI workflows that process untrusted GitHub content as high risk when they also have access to secrets, file read tools, or external communication channels.”

The OWASP Agentic Skills Top 10 project has formalized this with their B1-B4 trust boundary framework, mapping how individual skill risks chain across trust boundaries from developer intent to production deployment.

Defensive Patterns That Actually Work

If your organization runs AI agents in CI/CD, here is what the post mortem evidence says works:

1. Sandbox Before the Agent Starts

The Gemini CLI flaw executed before the sandbox initialized. Your container isolation, your drop-sudo, your read only filesystem — none of it matters if the agent’s launcher parses untrusted configuration before those controls engage. Treat the agent bootstrap itself as an attack surface. Pin configurations. Never load .env files from checked out repositories in CI.

2. Principle of Least Privilege for Agent Runners

OpenAI’s remediation separated Codex passes into different jobs and dropped to a read only sandbox. Apply this universally:

# Instead of this:
permissions:
  contents: write
  pull-requests: write

# Grant only what the agent actually needs:
permissions:
  contents: read
  issues: read

Agents that triage issues need read access. They do not need write access to secrets, packages, or deployments.

3. Validate Inputs Before Agent Invocation

Do not hand raw issue bodies to an agent. Strip, sanitize, and structurally validate untrusted content before it enters the agent’s context window. Consider a preprocessing step that extracts only the fields the agent needs:

# Pre-process issue content before agent invocation
sanitized = {
    "title": strip_markdown(issue.title)[:200],
    "body": strip_code_blocks(issue.body)[:2000],
    "labels": issue.labels,
}
# Only pass structured data to the agent
agent.invoke(context=sanitized)

4. Separate Trusted and Untrusted Passes

The Codex finding showed that running multiple agent passes in a shared job creates instruction injection opportunities. Each agent invocation should run in an isolated job with its own checkout, its own credentials, and no shared mutable state with other steps.

5. Treat Instruction Files as Untrusted Input

AGENTS.md, .gemini/, .claude/, CONVENTIONS.md — any file the agent reads as instructions is part of the untrusted input surface if an attacker can write to it. Pin instruction content outside the repository checkout, or verify checksums before loading.

The Broader Architectural Lesson

The zero trust community has spent a decade saying “never trust, always verify.” AI agents invert that principle by design: their entire purpose is to take loosely structured input and autonomously decide what to execute. The agent is a trust amplifier — it takes low privilege input and converts it into high privilege actions.

This means your threat model needs a new node. Between “untrusted external input” and “privileged CI execution,” there is now an agent that makes autonomous decisions about what to run. That agent is not a firewall. It is not a WAF. It has no deterministic security boundary. It is a probabilistic system making tool call decisions based on whatever context it was given.

Zentera’s zero trust architecture for agentic AI puts it cleanly: treat every AI agent as an untrusted principal that must authenticate, operate within a defined boundary, and produce an auditable record of every action it takes.

Your Call to Action

If your organization uses AI coding agents in CI/CD:

  1. Audit your triggers. List every workflow an external user can activate (issues, PRs, comments, forks). If any of those trigger an agent, you have an untrusted input → agent execution path.

  2. Audit your permissions. What secrets, tokens, and write access does the runner hold when the agent executes? Reduce to absolute minimum.

  3. Update immediately. Gemini CLI ≥ 0.39.1, run-gemini-cli ≥ 0.1.22, Claude Code ≥ 2.1.163. Pin these versions explicitly in your workflows.

  4. Instrument. Log every tool call the agent makes. If you cannot produce an audit trail of what the agent executed and why, you cannot detect compromise.

  5. Assume breach. Rotate any secrets that were accessible to agent workflows running the vulnerable versions. CISA lists no known exploitation, but a public reproduction lab for the Claude Code flaw has been on GitHub since June 18.

The agents are not going back in the box. But treating them as trusted components in a pipeline they share with untrusted inputs is an architecture that Black Hat just proved broken. Fix the harness.

A zero privilege GitHub account opens an issue on a public repository. No fork, no pull request, no commit access. Forty seconds later, arbitrary code is running on the CI runner behind that repository with full access to workflow secrets. The repository belongs to Anthropic, Google, or OpenAI.

That is...

EC2 Turns 20 — What Cloud Architecture Looked Like Then vs. Now

Twenty years ago today, Jeff Barr published a blog post announcing the Amazon EC2 Beta. One instance type. One Region. A 1.7 GHz Xeon slice with 1.75 GB of RAM, 160 GB of local disk, and 250 Mbps of network bandwidth — yours for $0.10 per hour. No persistent storage. No VPC. No load balancer. You launched an m1.small into a flat, shared /8 network, crossed your fingers, and hoped your app stayed up.

Today, EC2 spans over 1,200 instance types across 39 Regions, powered by five generations of custom silicon. The distance between that 2006 launch and what architects build on today is the story of how cloud infrastructure matured from a clever hack into the foundation of modern computing.

I’ve been using EC2 since 2009 — before VPCs existed, before IAM roles for instances were a thing, before you could even attach a persistent disk without downtime. I remember SSH’ing into instances that lived in a flat, shared network with every other AWS customer, praying that my Elastic IP reassignment would propagate before traffic started dropping. The platform has come an extraordinary distance since then, and this anniversary feels personal. Let me walk you through the arc.

The Original Architecture: 2006–2009

If you launched an instance in August 2006, your architecture looked something like this:

Internet → Public IP (assigned at boot) → m1.small → Local ephemeral disk

That was it. There was no Elastic IP, no persistent block storage, no way to define network topology. Every customer’s instances lived in a single giant 10.0.0.0/8 network — what we now call EC2 Classic. Security groups existed but operated at the instance level in a shared flat space.

The foundational primitives arrived in rapid succession:

  • 2008 — Elastic Block Store (EBS) gave instances persistent storage that survived termination
  • 2009 — Elastic Load Balancing, Auto Scaling, and CloudWatch made apps scalable and observable
  • 2009 — Virtual Private Cloud (VPC) introduced logically isolated networks with subnets, route tables, and gateways

VPC was the architectural inflection point. For the first time, you could design network topology — public subnets, private subnets, NAT gateways, peering connections. The multi tier web application pattern that defined a generation of cloud architecture became possible only after VPC existed.

The Nitro Revolution: 2017

For the first decade, EC2 ran on the Xen hypervisor. Networking, storage, and management functions all competed for CPU cycles on the host. Every packet your application sent had to traverse the same general purpose processor running your workload.

AWS began offloading these functions to dedicated hardware as early as 2013 with the C3 instance family, but the full Nitro System arrived in November 2017. The architecture changed fundamentally:

┌─────────────────────────────────────┐
│          Customer Instance          │
│    (nearly bare metal performance)  │
├─────────────────────────────────────┤
│         Nitro Hypervisor            │
│    (lightweight, minimal attack     │
│     surface)                        │
├───────────┬───────────┬─────────────┤
│ Nitro Card│ Nitro Card│  Nitro Card │
│ (Network) │ (Storage) │ (Mgmt/Sec)  │
└───────────┴───────────┴─────────────┘

By moving networking, storage I/O, and instance management onto purpose built Nitro Cards, AWS freed the host CPU entirely for customer workloads. The result: near bare metal performance with the security boundary of a hypervisor. Every EC2 instance launched since early 2018 runs on the Nitro System.

In 2026, AWS pushed isolation even further with the Nitro Isolation Engine — a component inside the Nitro Hypervisor that uses formal verification to provide mathematical proof that customer workloads are isolated from each other and from AWS operators. Not just “trust us” — cryptographic, formally verified assurance.

Custom Silicon: Graviton and the AI Accelerators

The Nitro System made a second revolution possible. Once the hypervisor was thin and the I/O offloaded, AWS could drop in any processor architecture without re-engineering the platform.

Graviton timeline:

Generation Year Key Advancement
Graviton (A1) 2018 First Arm based instances, up to 45% cost reduction for scale out workloads
Graviton2 2020 40% price performance over x86, broad adoption
Graviton3 2022 25% better compute over Graviton2, DDR5 memory
Graviton4 2024 30% better performance, 75% more memory bandwidth
Graviton5 2025 192 cores, 5x larger cache, optimized for agentic AI workloads

Today’s M9g instances (Graviton5, sixth generation Nitro) are so architecturally distant from the original m1.small that they share little beyond the “general purpose” label. And they’re running workloads — real time reasoning, multi step orchestration, code generation — that did not exist as categories in 2006.

AI accelerators followed a similar trajectory. Inferentia (2019) brought purpose built inference silicon. Trainium (2021) tackled training. By late 2025, Trn3 UltraServers interconnect up to 144 Trainium3 chips to train and serve frontier models. The progression from “rent a virtual CPU” to “reserve a 144 chip training cluster” happened in under 20 years.

What This Means for Architects Today

The architectural decisions you face in 2026 are qualitatively different from 2006, but the meta pattern is the same: match the workload to the right primitive.

Here’s what a modern EC2 launch looks like compared to 2006:

# 2006: Launch an m1.small. That's all there was.
ec2-run-instances ami-xxxxxxxx -t m1.small

# 2026: Launch a Graviton5 instance in an isolated VPC with IMDSv2 enforcement
aws ec2 run-instances \
  --image-id ami-0abc123def456 \
  --instance-type m9g.2xlarge \
  --subnet-id subnet-0a1b2c3d4e \
  --security-group-ids sg-0f1e2d3c4b \
  --metadata-options "HttpTokens=required,HttpEndpoint=enabled" \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Environment,Value=prod}]'

The CLI call got longer because the platform got richer. Every additional flag represents a decade of lessons learned about security, cost, and operational maturity.

Practical Takeaways

  1. Default to Graviton. Unless your workload has a hard x86 dependency (specific licensed software, architecture specific binaries you cannot recompile), start with Graviton instances. The price performance advantage is real and compounding with each generation.

  2. Understand the Nitro System boundary. The security model of modern EC2 is fundamentally different from pre-2017 instances. Network and storage I/O never touch your host CPU. The Nitro Isolation Engine provides formally verified separation. Design your threat models accordingly — the Nitro System security whitepaper is essential reading.

  3. Use purpose built instances for AI workloads. Running inference on general purpose instances is like using a sedan to haul freight. Inf2 for inference, Trn2/Trn3 for training, and EC2 Capacity Blocks for reserving GPU/accelerator time exist specifically to avoid overpaying for the wrong compute shape.

  4. Treat instance selection as an architectural decision, not a default. With 1,200+ instance types, the “just pick an m5.large” reflex leaves performance and money on the table. Profile your workload, right size with AWS Compute Optimizer, and revisit quarterly as new generations launch.

  5. Remember that EC2 is still the foundation. Lambda, Fargate, EKS, SageMaker, Bedrock — they all run on EC2 underneath. Understanding the compute layer makes you a better architect regardless of the abstraction you choose to expose to your application.

Looking Forward

EC2’s first 20 years traced an arc from a single shared network with one instance type to a global, multi architecture platform with mathematically proven isolation and purpose built silicon for every workload class. The next 20 will likely be defined by AI native compute patterns, disaggregated architectures, and deployment models we have not yet named.

But the core principle that made EC2 transformative in 2006 has not changed: give builders the primitives, make them minimal yet useful, and iterate relentlessly based on what they actually build. Twenty years in, that flywheel is still spinning.

Happy birthday, EC2. Here’s to the next twenty.

Twenty years ago today, Jeff Barr published a blog post announcing the Amazon EC2 Beta. One instance type. One Region. A 1.7 GHz Xeon slice with 1.75 GB of RAM, 160 GB of local disk, and 250 Mbps of network bandwidth — yours for $0.10 per hour. No persistent storage....

Passed AWS Certified Security - Specialty

It’s been a heck of three weeks—actually, a month. I started studying on June 15th for the Network and AWS Solution Architect Professional, as the networking was expiring first. I decided I focus on one exam at a time. So I did the Professional Architect June 28th, Networking July 6th, and Security on July 16th. All of this while working full time. It reminded me of the effort required to get my Master’s Degree in Computer Science. I’m relieved, as I have my DevOps in November, but at least now there is a break.

Without violating the NDA, let’s talk about the security exam. I took the exam Friday and passed. I did the exam on Pearson Vue. For the exam, I used about 95 minutes, which is half the allocated time. Some questions were real struggles. Hopefully, I’ll remember some of the contexts and research them later for my knowledge. 

The last time I took the security exam in July 2018, I decided on a Friday to take it the following Wednesday. Last time I wrote, “It’s the hardest exam I’ve taken to date. I think it is harder than the Solution Architect - Professional exam.” In 3 weeks, taking the Solution Architect - Professional, Networking Specialist, and Security Speciality. Oh wait, this is the second time I’ve done this. I guess I haven’t learned. I would confirm it’s hard. Is it harder than the Solution Architect Professional in its current form? I don’t know. It’s a more nuisance exam focused on security. AWS has 100,000s pages of documentation on services, Well-Architected, Mitigation strategies, and this exam pulls from those documents. I’m not going to go into details about the questions. But that’s a ton of information to know and understand to achieve this certification. I guess this is why they’re hard, and few people have 11.  

Now the part I will talk about is my preparation. Security is fundamental to AWS. Every service integrates with IAM, most with KMS, and there are many other services like SCPs, Security Hub, Guard Duty, Shield, etc., designed to help protect workloads in AWS and their integration to other services. Last time I probably put 24 hours into studying for the exam. This time it was maybe 18 hours in total. I don’t think I did the preparation justice either time. I think I fell back on my 12 years of AWS experience and the past three weeks of studying for the other exams. Although I knew going into the exam areas like KMS Key Grants, Private CA on ACM, HSM, Secrets Manager were weaknesses, the more I tried to read up and watch videos, the more learning I felt I needed imposter syndrome at work. 

I watched the 96% of acloud.guru security course did watch it at 1.75x- 2x speed. I didn’t slow down. If I didn’t understand a topic, I read or watched something in the resources section below. Again these are resources collected before the exam that I used. 

Resources

It’s been a heck of three weeks—actually, a month. I started studying on June 15th for the Network and AWS Solution Architect Professional, as the networking was expiring first. I decided I focus on one exam at a time. So I did the Professional Architect June 28th, Networking July 6th,...

Security Reference Architect

AWS has the security shared responsibility model.
Shared Responsibility Model

Anyone on the AWS platform understands where this model. However, security on AWS is not easy as AWS has always been a platform of innovation. AWS has released a ton of services AWS Config, Macie, Shield, Web Application Firewall, SCPs. Over the years, Landing zones and then Control Tower which builds security when starting multi-account on AWS. Lastly, the Well Architected Security Pillar to review and confirm your workload is well architected.

Last month, AWS released a comprehensive guide to a Security Reference Architecture. It was built by Professional Services, which is the customer implementation arm of AWS.

I’m not going to try to summarize a 62-page document in a blog article. Mainly the document is about defense-in-depth, which is security at each layer of the workload. There two key observations from the document. The first observation is it does follow Control Tower guidance. Terms have been changed. It requires workloads to be in separate OU from security and infrastructure(shared services). Again these are general security principles that limit blast radius if an application or account is compromised. Security account and log collection account need to be separate. This Control Tower recommended an OU structure. Also, keeping log data in an immutable state is best for audit analysis.

The second observation is it now talks about leverage the Infrastructure account for Egress and Ingress traffic to the internet. This is only possible with Transit Gateway or a Transit VPC, defined in the document but not mentioned as part of the VPC diagram.

Maybe it’s just because of hyperfocus on renewing certifications. However, I notice the bleed-over between networking and security and how proper networking architecture is to start good security hygiene.

AWS has the security shared responsibility model.
Shared Responsibility Model

Anyone on the AWS platform understands where this model. However, security on AWS is not easy as AWS has always been a platform of innovation. AWS has released a ton of services AWS Config,

Transit Gateway and Direct Connect

After studying for Advanced Networking Exam, I pondered a question about global backbones. There is a need for common understanding. So let’s take a step back. Transit gateway was a service introduced at ReInvent 2018. Transit Gateway(TGW) puts a router between VPCs and other networking services. The transit gateway works by putting attachments in each VPC using ENIs. If you’re lost before proceeding, watch the Re: Invent Video. TGW uses attachments is fundamental to the VPC architecture as the VPC doesn’t process traffic from a source destination outside the VPC. So the attachment ENI becomes part of the VPC. So now I have an attachment in the VPC thru a subnet. So instead of terminating my DirectConnect Gateway(DXGW) on a VGW in a VPC, it’s terminated in a TGW. A quick whiteboard of this architecture.
Transit Gateway

This becomes challenging while building a global network because European network would look like this assuming I had three pops in one Europe region:
Transit Gateway with multiple POPs

Still better than Direct Connect Gateways to the VPCs. But there is a limitation Transit Gateways which are peered, don’t dynamically pass routes. This works great if you summarize routes by region. Like the US was all 10.50.0.0/12, and Europe was all 10.100.0.0/12. What doesn’t work is when I have unsummarized routes. But I digress route summarization doesn’t matter to the question. So here is a quick view of our whiteboard architecture of Europe and US regions: Transit Gateway with multiple POPs

The question is if there was dynamic routing, could I use the AWS backbone to haul traffic around the world without having to build my own global network as the two TGWs would exchange my prefixes from the exchange or pop locations?

After studying for Advanced Networking Exam, I pondered a question about global backbones. There is a need for common understanding. So let’s take a step back. Transit gateway was a service introduced at ReInvent 2018. Transit Gateway(TGW) puts a router between VPCs and other networking services. The transit gateway works...

Passed the AWS Certified Advanced Networking – Specialty Exam

I needed to recertify the Advanced Networking specialty. Technically it expired on 6/20. So I decided to focus on the Professional as it would include Networking and Security topics. I need to recertify Security Speciality later this month.

I took the AWS Advanced Networking Speciality on Tuesday and passed.

I took this exam with Pearson VUE. The exam opens 30 minutes before to get checked out. The process with the same as PSI, only there wasn’t a long wait. Personally, the interface in PSI is a little nicer than Pearson VUE. However, the experience of the otherwise of taking the exam is the same as it’s from the comfort of home.

I’m not going to talk about the exam, as that would violate the NDA. There are three observations. First, the exam requires deep AWS networking knowledge. Make sure you get in the console and get hands-on. The exam, as advertised, requires deep understanding and experience, which can only come thru practical hands-on experience. The other observation I would make is that the exam requires knowledge of services touched by networking, which is why acloud.guru course recommends associate level certification. The last comment on this exam has the most deficient written questions and answers of the certification exams I’ve taken. The questions and answers lack clarity found on the other exams.

I took the exam in about 90 minutes, which is half the allocated time. There were enough questions that I struggled to know the correct answer. I had no sense if I had no sense during the exam of a pass or fail.

Now the parts I can talk about, which was my preparation for the exam. In studying, the number of new networking specific services, including Transit Gateway announced Re:Invent 2018, Firewall Manager introduced April 2018 to name a few. The changes in networking services like AWS Shield, VPC FLow Logs, WAF between studying back in 2018 and studying three years later is incredible. Probably the reason, these certifications have to be re-certified every three years. The first time for the exam, I put about 50 hours of preparation into studying for the exam. This time I put maybe 16 hours into studying.

I watched about 80% of the acloud.guru course. I did watch most of it in 1.75x speed. I would slow down if I didn’t understand a topic or wanted more. I also read many whitepapers and FAQs and watched Youtube videos (2x) and linked below.

Resources:

I needed to recertify the Advanced Networking specialty. Technically it expired on 6/20. So I decided to focus on the Professional as it would include Networking and Security topics. I need to recertify Security Speciality later this month.

I took the AWS Advanced Networking Speciality on Tuesday and passed.

I...