A missed from Pwn2Own Berlin 2026 and Full Disclosure on LMStudio RCE
I thought I was going to Berlin. I had submitted my entry, received an invitation letter, and spent AUD $300 on expedited visa processing. I had working bugs…
I thought I was going to Berlin. I had submitted my entry, received an invitation letter, and spent AUD $300 on expedited visa processing. I had working bugs and teammates preparing their own chains.
What I did not have was an assigned token.
That was how my attempt to compete at Pwn2Own Berlin 2026 ended. It started as an experiment in using LLMs to find zero-days and turned into a frustrating lesson about competition registration, communication, and the gap between submitting an entry and actually getting a place.
It also produced an LM Studio RCE chain that deserves its own write-up.
It started with an experiment
Around March and April 2026, I decided to test how useful LLMs could be for finding zero-day vulnerabilities. Pwn2Own gave me a concrete goal: find remote code execution bugs in software on the target list.
I focused on the Coding Agent and Local Inference categories. Together, they covered seven targets: Claude Code, OpenAI Codex, Cursor, Ollama, LiteLLM, LM Studio, and llama.cpp. The categories and their requirements are listed in the Pwn2Own Berlin 2026 rules.
I teamed up with j3ssie and Peng Aik Goh for the competition.
The question I wanted to answer was practical: could LLM assistance help us find real vulnerabilities that crossed security boundaries and led to code execution?
We found enough to get excited.
April 16: submitted, invited, and apparently going to Berlin
I submitted my entry on April 16, 2026. From my perspective, that was early enough to feel reasonably confident about the process.
Then I received an invitation letter from TrendAI to support my visa application.
At that point, I thought the trip was happening. An invitation letter for a visa felt like a pretty strong signal that I would be attending and participating.
LM Studio was my favorite finding because the chain connected several pieces into a clean RCE. I will get to that below. I also found bugs in Claude Code, Codex, and Cursor—some of the kind that make you stare at the result and think, “Really? That worked?”
Peng Aik Goh found four more vulnerability chains as well.
There was a lot of work behind those submissions, and we were looking forward to demonstrating it.
The token I did not know I needed
This was where my understanding of Pwn2Own fell apart.
I did not understand that I needed an assigned token to actually participate. In my head, submitting the entry and receiving an invitation letter meant I was moving toward a competition slot. In practice, I was still missing the confirmation that mattered.
This post from __suto was the moment that brought the token issue into focus for me.
By then, I felt ghosted by Trend Micro. I had an invitation letter for my visa process, but I did not have an assigned token or the clarity I needed to plan around that distinction.
And yes, I had already paid AUD $300 out of my own pocket for fast visa processing. Ouch.
I can accept that a competition has limited capacity. The frustrating part was believing I was going, spending money on that basis, and only later understanding that my participation was still uncertain.
Too many submissions, and the LLM question
My impression was that Pwn2Own was facing a huge volume of submissions, and I suspect the rise of LLM-assisted vulnerability research contributed to that pressure. I do not have the organizers’ submission statistics or their internal selection decisions, so I cannot prove that LLMs caused me to miss the competition.
But the connection was hard to ignore from where I was sitting. I had started this whole effort to test whether LLMs could help find zero-days. If other researchers were doing the same thing, it was easy to imagine the submission queue growing much faster than the available competition slots.
That does not mean every AI-assisted submission was valid, unique, or competition-ready. More submissions still require more review, and an exploit still has to work. But the experience left me wondering whether the competition process was ready for the volume that these tools could enable.
There was plenty of frustration in public, too. Memes, angry posts, and a lot of swearing captured the mood better than a polite recap could.
This post from h0mbre_ is another reference from that period.
For me, the lesson was expensive and simple: next time, I need explicit confirmation of a competition slot before treating the trip as settled.
Full Disclosure: LMStudio RCE
As the competition demonstration dates approached, I reported the LM Studio zero-day directly to the vendor. I emailed LM Studio’s CTO with the details.
Full disclosure zip
My email to the CTO:
The chain had two entry paths. One started with a victim visiting a malicious website while running LM Studio with CORS enabled. The other started with an attacker who could reach an LM Studio server exposed on the network. Both reached the same dangerous behavior: using the server’s WebSocket interface to download and automatically execute an attacker-controlled plugin.
The explanation below describes the behavior I observed during my research. It does not establish the affected version range or the current patch status.
Path 1: malicious website → reflected XSS → plugin execution
The first path involved LM Studio’s server running locally on its default port, 1234, with CORS enabled.
The relevant setting:
In this setup, the victim only needed to visit an attacker-controlled website to start the chain. The website triggered a reflected XSS vulnerability in the LM Studio service at localhost:1234.
The CORS setting mattered because LM Studio only registered the vulnerable route when CORS was enabled. With CORS disabled, that route did not exist, so this reflected XSS entry point was unavailable. Once the XSS executed in the local service’s origin, the injected script did not need CORS permission to make same-origin requests.
In my tested chain, executing in the local origin let the script get past Chrome’s Local Network Access barrier and reach the local WebSocket interface. LM Studio also checked the WebSocket handshake’s Origin header and required the localhost origin. The XSS satisfied that check because the browser was executing the script from http://localhost:1234.
Once running in the local origin, the script interacted with LM Studio’s WebSocket interface on localhost:1234. It used that interface to trigger the download of an attacker-controlled plugin hosted under an LM Studio Hub repository, following the https://lmstudio.ai/:username/:repo structure.
For my Pwn2Own attempt, I used phvietan/open-calc. As the name suggests, the demonstration payload opened Calculator.
The decisive behavior came after the download: the WebSocket-triggered flow automatically ran the malicious plugin. That turned control of a browser script into code execution on the machine running LM Studio.
The chain looked like this:
- The victim runs LM Studio with CORS enabled, making the vulnerable route available.
- The victim visits a malicious website.
- The website triggers reflected XSS in the local LM Studio service.
- The injected script interacts with the local WebSocket interface.
- The service downloads the attacker’s plugin and automatically executes it.
- The attacker’s code runs on the victim’s machine.
Opening Calculator was the visible proof. The security impact was the ability to execute attacker-controlled code through that plugin flow.
Path 2: network-exposed server → plugin execution
The second path skipped the browser and reflected XSS entirely.
When LM Studio’s server was started with --bind 0.0.0.0, it listened on all network interfaces. If an attacker could reach the server over the network, they could interact directly with its WebSocket interface at server_ip:1234 and trigger the same plugin download and execution flow.
This path depended on network reachability. Binding to 0.0.0.0 does not automatically make a server reachable from the internet; routing, firewalls, and the surrounding network still determine who can connect.
But in the reachable configuration I tested, the attacker did not need to lure the victim to a website or use the reflected XSS. Direct access to the exposed service was enough to reach the shared RCE mechanism.
Demonstration video
Here is the recorded demonstration:
No Berlin stage, but still a story to tell
I started this project to see what LLM-assisted zero-day research could produce. I ended up with bugs, a team preparing multiple chains, an invitation letter, a visa bill, and no assigned token.
I am still frustrated about how the competition side played out. I wish the difference between an invitation letter and a confirmed competition slot had been clear to me before I spent money.
The research was still worth doing. The LM Studio chain gave me a concrete result from the experiment, and reporting it directly to the vendor gave the finding somewhere to go after my competition plans fell through.
Happy hacking guys !
Join the conversation
No account needed