OpenCode Got Hacked Badly (My API Keys Got Drained)
“You can only show the real first and last eight characters if the real key is what's stored.”
FULL TRANSCRIPT
You know that specific kind of dread
when you check your email in the
morning, half asleep and still holding
your coffee and the subject line says
unusual activity on your account and
your stomach just drops. Now imagine
that email is from Open AI or Anthropic
and instead of we noticed a login from a
new device, it says your API key was
used for 35 million tokens overnight
while you were asleep. That is not a
hypothetical. It happened to real
developers who were just building stuff
with AI tools and woke up to bills they
never ran up. One person lost $16 and
another person hit by the same attacker
on the same night lost $3,000.
And the crazy part is that the gap had
nothing to do with who the hacker was or
how sophisticated the attack was because
it came down to one setting that most of
us never even thought to set up. So, I'm
going to walk through what actually
happened with the Open Code hack and
then what we should all change before we
become the next person posting in a
developer forum at 2 a.m. asking why our
account just got drained. If you haven't
used Open Code, the short version is
that it is an AI coding assistant that
lives right inside the terminal, which
is where the code actually happens
anyway. And it lets us bring Claude,
GPT, Gemini, and the rest right there
alongside the work. I've been using
tools like this and the pitch really is
hard to resist. When we're three levels
deep into some rabbit hole, we just ask
right there instead of all tabbing out
to a browser and it feels like the
future. And that context matters for
understanding why so many developers
trusted it with their API keys since it
was not carelessness at all. And the
whole point of the tool is that you
paste your key in and everything just
works. Now this distinction is going to
matter a lot in a minute. Open code has
two parts. There is the terminal app
which runs locally on your machine and
then there is the console which is open
code's web dashboard. It works like a
settings panel in the browser where you
manage workspaces and paste in your own
API keys to use through their servers.
And that second part, the conso's bring
your own key feature is where everything
went wrong. When we look at the
timeline, I want you to notice not just
what happened, but how fast it escalated
because it is kind of terrifying. It
starts on Saturday, October 17th at 0:30
UTC, which is the middle of the night
for most of the world. That is the
moment when what Open Code later
described as a breach of a legacy system
apparently begins. Now, for a few hours,
nothing publicly visible happens while
the world is asleep and the keys are
just sitting there. And then at around 2
am Eastern, which is 6 a.m. UTC, a
developer named Colin Parsons watches
his Open AI key get pounded, which is
his word, not mine, for $281 worth of
API calls. And then his anthropic key
goes for another $168,
all within hours. Both keys, he said
later, had only ever been used in open
code. And that last part is what locks
this in because it was not a reused
password or some fishing site. So the
only place those keys had ever lived
outside his own machine was inside Open
Code's console. So he does what any
developer would do, which is post about
it publicly and ask Open Code directly
whether they'd been hacked. Within the
hour, someone else replies with a $1,700
loss. And then Matt Johansson posts
confirmed, open code hacked, key stolen,
and that post gets almost 800,000 views.
But Open Code's first public statement
does not go up until 1756 UTC, which is
17 1/2 hours after the exposure window
opened. To be fair, that's not nothing,
and they were clearly scrambling
internally. But from the outside,
watching people post their losses in
real time while waiting for official
word was rough. And the detail that
really got me is that some of the
providers moved faster than Open Code
did. One user said OpenAI warned him 9
hours before Open Code did. And
Anthropics Lydia Halley posted at 9:00
p.m. that they had already revoked the
clawed API keys they believed were
affected. So the company that lost the
keys was the last one to tell people.
Now we get to the part I find genuinely
fascinating from a technical standpoint
and also depending on how you look at
it, slightly face palinducing. Open
Code's official email to affected users
described the breach as reaching a
legacy system that we were in the
process of decommissioning. And that
phrase sounds like a dusty server in a
closet, something from years ago that
nobody uses anymore. But the actual
story is a little different. Open Code's
code is public, so anyone can read it.
And if we go and look, there's a commit
from Monday, October 12th, 5 days before
the breach, called remove legacy
database from console, which sounds
pretty thorough, right? But production
systems do not quite work that way. And
this is a nuance that matters. When you
deploy code, the code you deploy owns
the things it creates. But if a database
already existed before your code and
your code just had a pointer to it, then
deleting the pointer doesn't delete the
database which just sits there
unconnected and no longer used by the
new system but still very much alive.
What the deploy actually did was delete
the old login service and the database
password that lived in the new codebase.
The production database itself, the
actual thing holding the keys, was not
something that deploy had the authority
to wipe. So it was still out there and
in the dev environment the attempt to
delete it failed three times because it
was protected from deletion. So legacy
doesn't mean a forgotten relic from 5
years ago. It means a database the new
system had stopped pointing at still
holding live API keys 5 days after
somebody wrote a commit saying they had
removed it. I want to be fair here
because this kind of thing happens and
migrations are hard. Anyone can write a
commit in good faith called remove
legacy database and not realize the
production database isn't owned by their
deployment process. Still 5 days is not
a lot of time. There is one more
technical detail about how this data was
stored and I'm going to walk through it
carefully because it matters. In the old
database schema which is also visible in
open codes public repo. Your API key
went into a table called provider into a
column called credentials stored as
plain text which means it was not hashed
and it was not encrypted at the
application level. So it was just a raw
string exactly as you pasted it in. Now
to be fair there is context here because
database hosts almost always encrypt
data at rest. Meaning the files on disk
are scrambled. So it's not like anyone
with physical access to a hard drive
could read the keys off a platter. But
encrypted at rest and stored as plain
text can both be true at the same time.
This encryption protects against someone
stealing the physical hardware, but it
does nothing against someone who gets
access to query the database. And any
process that could run a select
statement on that table could read every
key in full. And the detail that
confirms it is the settings page. It
shows a masked version of your key with
the first eight characters and the last
eight and asterisks in the middle. And
in the code, that mask is generated from
the stored value. You can only show the
real first and last eight characters if
the real key is what's stored. And if
they had stored a hash, the masking
wouldn't work. So the keys were all
there, readable by anything with
database access. I'm not saying this to
pile on open code because they are
clearly making fixes and their founders
GET MORE FROM YOUR TRANSCRIPTS
Sign up for free and unlock interactive viewer, AI summaries, translations, concept maps, and more. No credit card required.