Try reloading the player or open this episode directly on YouTube.
This episode of Ship It Weekly discusses AWS's new Elastic Beanstalk Cluster Mode, enabling multiple apps on shared EKS infrastructure. It also covers CrowdSec's supply-chain breach, a critical Next.js RCE vulnerability, and Microsoft's disruption of the EvilTokens platform.
Now Playing
AWS Puts Elastic Beanstalk on EKS, CrowdSec Supply-Chain Breach, Critical Next.js RCE, Microsoft Disrupts EvilTokens & Why Fixing the Initial Compromise Isn’t Enough
Ship It Weekly
0:0017:18
Chapters
Jump to a section in this episode.
Speed & share
Transcript
AWS is putting Elastic Beanstalk on top of shared
Kubernetes infrastructure. A compromised developer
token helped attackers copy roughly 170 private
CrowdSec repositories. And Microsoft just disrupted
a cybercrime platform using AI to figure out
not just what to say, but who inside a company
was worth impersonating. I'm Brian Teller from
Teller's Tech, and this is Ship It Weekly. Welcome
back to Ship It Weekly, the show about the DevOps,
SRE, Cloud, platform and security stories that
matter when you are the person keeping the thing
running at three in the morning. For the weekly
story list and source links, check out
OnCallBrief.com. For past episodes and show notes, head
over to ShipItWeekly.fm. This week, AWS is rebuilding
the Elastic Beanstalk model around shared EKS
infrastructure. We have a software supply-chain
compromise that eventually led to CrowdSec losing
private source code. There is a critical remote
code execution vulnerability in Next.js. And
Microsoft has disrupted EvilTokens, a cybercrime
platform that compromised more than 12,000 inboxes.
Then we have a quick lightning round and a human
closer about why fixing the thing that got compromised
does not necessarily end the incident. Let's
get into it. First up, AWS has introduced cluster
mode for Elastic Beanstalk. And this is an interesting
direction for a service that has been around
since 2011. Traditional Elastic Beanstalk environments
generally give an application its own infrastructure.
Cluster mode changes that. Multiple applications
can now run on pooled infrastructure powered
by EKS. You can give Beanstalk source code, a
Dockerfile, or an image from ECR, and AWS handles
the infrastructure underneath it. That includes
deploying and scaling the application, patching
the environment, and managing the EKS infrastructure.
It also includes event-driven autoscaling, OpenTelemetry-based
observability, Secrets Manager integration,
and HTTPS through ACM. There is no separate charge
for cluster mode, but you are still paying for
the EKS cluster, EKS Auto Mode, and the resources
your applications consume. I think the interesting
part here is the abstraction. For years, a lot
of platform engineering has basically been we
standardize on Kubernetes. Now, how do we stop
every developer from needing to understand Kubernetes?
This is another answer to that question. Developers
get something closer to a platform as a service.
AWS gets Kubernetes underneath it. But shared
infrastructure also means you should understand
what is actually shared. Cost efficiency is
one side of pooling workloads. Isolation, resource
contention, upgrades, and blast radius are the
other side. You may not need to operate the cluster
anymore. You should still understand what happens
when the cluster has a bad day. Next, CrowdSec
published an analysis of how attackers were able
to copy roughly 170 of its private GitHub repositories.
And the interesting part is how far back the
story starts. In May, attackers compromised packages
associated with TanStack and used malicious code
designed to harvest credentials and tokens. According
to CrowdSec's investigation, a stolen OAuth token
was later used to download its private repositories.
The repositories were copied in roughly nine
minutes. CrowdSec says the token no longer existed
by the time it became aware of the leak, and
it could not find the token in the audit data
it had available during the investigation. That
is a much more useful supply-chain story than
simply saying an npm package got compromised.
Because the package compromise was only the beginning.
The useful thing the attacker got was access.
Once credentials leave the machine, patching
the original package does not magically pull
them back. That is where incident response can
get uncomfortable. What credentials existed on
that machine? What could they access? Are they
still valid? Were they copied somewhere else?
Did the attacker create another way back in?
And what evidence do you actually have available
to answer those questions? Removing the malware
matters. Rotating and tracing the credentials
it may have touched matters just as much. Third,
there is a critical remote code execution vulnerability
affecting Next.js. CVE-2026-94545 affects
versions 16.2.0 through 16.3.5 and has been
patched in 16.3.6. The issue is in the Node.js
implementation of ImageResponse from
next/og. If an application passes attacker-controlled
data into SVG content, attributes, or styles
during image generation that can lead to remote
code execution. The Edge implementation is not
affected. And applications that do not pass attacker
-controlled values into that SVG generation path
are not affected either. What I like about this
story is how harmless the vulnerable functionality
sounds. Image response is commonly used to generate
things like Open Graph images. You publish a
page. Somebody shares the link. Your application
dynamically generates the social preview image.
It is easy to mentally put that in the same category
as resizing an image or generating a thumbnail.
Except this is server-side rendering logic processing
input. And if some of that input comes from a
URL parameter, database field, user profile,
CMS, or somewhere else an attacker can influence,
it is no longer just presentation. It is untrusted
data entering a server-side rendering path.
That is the part that I would check in addition
to just checking the version number. Where are
we using ImageResponse? What data gets passed
into it? Where did that data originate? And can
someone outside the application control any of
it? That is also why dependency vulnerabilities
can be hard to triage from a scanner alone. The
scanner can tell you you have a vulnerable version
of Next.js. It cannot always tell you whether
your application actually exposes the vulnerable
code path. You still need to understand how the
software is being used. If you are running an
affected Next.js release and using the Node
.js ImageResponse implementation, update to
16.3.6. And if you cannot update immediately,
the workaround is straightforward. Do not pass
attacker-controlled values into SVG content,
attributes, or styles rendered through that implementation.
Fourth, Microsoft says it has disrupted Evil
Tokens. EvilTokens was a cybercrime platform
that combined phishing, account compromise, mailbox
analysis, and AI-assisted fraud. Since launching
in February, Microsoft says it was linked to
more than 12,000 compromised inboxes across
more than 10,000 organizations. Microsoft seized
50 websites and disabled more than 150 additional
domains connected to the operation. What makes
EvilTokens different from the usual AI phishing
story is what happened after an account was compromised.
The platform could analyze a victim's mailbox
and identify trusted relationships, payment conversations,
financial responsibilities, and people worth
impersonating. So instead of just, "Write me a convincing phishing
email," it could help answer, "Who does this person
trust? Who approves payments? Which conversation
can I insert myself into?" And, "Who should I pretend
to be?" Microsoft says EvilTokens also used device
code phishing. And this is worth explaining because
it can look a little different from the phishing
flow people expect. Device code authentication
exists for devices or applications where normal
interactive login is inconvenient. The application
gives you a code. You go to a legitimate Microsoft
login page on another device. Enter the code,
authenticate, and the original application gets
authorized. The problem is that an attacker can
initiate that flow too. They get the device code
and convince the victim to enter it. The victim
may be on Microsoft's real login page. They may
complete their normal authentication. They may
even complete MFA. But the session being authorized
belongs to the attacker. So MFA did its job.
It verified the user. The user was just tricked
into authorizing the wrong session. Once Evil
Tokens had mailbox access, Microsoft says it
could analyze the contents and help identify
useful relationships and financial conversations.
Stolen access could also be maintained with malicious
inbox rules that hid communications. That makes
this less about AI magically creating a new kind
of attack. Account takeover and business email
compromise are not new. What changes is how quickly
an attacker can make sense of everything they
stole. 10,000 emails used to be a lot of information
for a person to work through. For a model, that
becomes data to classify. The defensive side
still looks pretty familiar. Control authentication
flows, protect tokens, watch for suspicious inbox
rules, and treat a valid authenticated session
as something that can still be malicious. Quick
lightning round. First, F5 has a critical big
IP APM vulnerability under active exploitation.
CVE-2026-94127 is a heap-based buffer overflow
affecting certain BIG-IP APM configurations where
an access policy and OAuth profile are configured
on the same virtual server. Successful exploitation
can result in unauthenticated remote code execution.
If that configuration applies to you, this is
a patch now item. Second, GitHub Enterprise Cloud
can now export an inventory of every credential
capable of accessing the enterprise. That includes
SSH keys, classic and fine-grained PATs, OAuth
tokens, and GitHub App credentials. The inventory
includes things like ownership, scopes, expiration,
last use, and which organizations or repositories
the credential can access. There is also a REST
API, which makes this much more useful for automated
credential hygiene. Third, Zyxel's GS1900 series
has a vulnerability that can allow an unauthenticated
attacker on the LAN to execute operating system
commands using a crafted HTTP request. Patches
are available for supported models. And fourth,
Veeam Agent for Microsoft Windows has a privilege
escalation vulnerability that can let a low-privileged
local user gain SYSTEM access. Public proof-of-concept
code is available. So if you are running
affected version 13 builds, get them updated.
The human closer this week comes back to the
CrowdSec story. One of the easiest mistakes
during incident response is assuming the incident
ends when you fix the thing that was originally
compromised. A malicious package gets removed.
A vulnerable server gets patched. A laptop gets
reimaged. Problem solved. Except the attacker
may have already gotten what they needed. A token.
An SSH key. A session. Cloud credentials. A package
registry credential. Something sitting in a config
file. Something sitting in memory. The original
compromise can last five minutes. The credential
stolen during those five minutes might work for
months. That is why containment has to extend
beyond the thing that got compromised. If a developer
workstation gets hit, I want to know what that
workstation could authenticate to. GitHub, AWS,
Kubernetes, package registries, CI systems, internal
services. And then I want to know which of those
credentials still exist. This gets harder when
your logs do not go back far enough. The token
has already disappeared, or you do not have a
good inventory of credentials in the first place,
which is actually why that GitHub credential
inventory item in the lightning round matters.
During an incident, "What credentials can access
this environment?" is a question you want to answer
immediately, not after three hours of spreadsheets
and Slack messages. Fixing the original vulnerability
stops one path in. It does not tell you what
walked out before you closed the door. That's
it for this week's Ship It Weekly. We covered
Elastic Beanstalk running applications on shared
EKS infrastructure, the CrowdSec supply-chain
compromise, a critical Next.js remote code execution
vulnerability, and Microsoft's disruption of
EvilTokens. Plus an actively exploited F5 vulnerability,
The thing that stuck with me most this week is how many of these stories are really about trust. Not necessarily whether you trust AWS, GitHub, Microsoft, or a particular open-source project, but what happens after your systems have decided something is trusted.
That is where a lot of the interesting infrastructure and security problems seem to live now.
Take the CrowdSec incident. The initial compromise was in the software supply chain, but that was not really the end result the attacker cared about. The valuable part was the credential they were able to get from it. Once that OAuth token existed outside the environment where it belonged, fixing the original package did not fix the larger problem.
According to CrowdSec, that stolen token was eventually used to copy roughly 170 private GitHub repositories in about nine minutes.
Nine minutes.
That is not much of an incident-response window.
By the time somebody realizes something is wrong, starts a Slack thread, pulls in security, checks the logs, figures out which account is involved, and starts revoking access, the actual data movement may have been over for hours, days, or longer.
And I think that changes how we should think about containment.
We spend a lot of time talking about initial access. Patch the vulnerability. Remove the malicious package. Reimage the developer laptop. Kill the process.
Obviously you need to do all of those things.
But the question immediately after that should be: what could this thing authenticate to?
If it was a developer workstation, that answer might be GitHub, AWS, Kubernetes clusters, package registries, CI systems, internal tooling, databases, artifact repositories, or half a dozen other things.
Then you have another question: what credentials were actually present?
That sounds simple until you try answering it during a real incident.
Some credentials are short-lived. Some are not. Some are sitting in environment variables. Some are managed by credential helpers. Some are PATs somebody created two years ago. Some exist in CI. Some belong to GitHub Apps. Some are SSH keys. Some are sessions that are already authenticated.
That is why the GitHub credential inventory announcement in the lightning round is more useful than it might initially sound.
Being able to ask, “Show me the credentials capable of accessing this enterprise, who owns them, what they can access, when they expire, and when they were last used,” is useful on a normal Tuesday.
During an incident, it can become one of the first questions you need answered.
The EvilTokens story approaches the same problem from a different direction.
The part that interests me is not really “hackers are using AI.”
We have heard some version of that story enough times already.
The more interesting part is what AI becomes useful for once an attacker already has access.
A compromised mailbox can contain years of information. Thousands or tens of thousands of emails. Vendor conversations. Invoices. Org charts. Travel schedules. Internal projects. Who approves payments. Who reports to whom. Which vendors regularly ask for money. How the CFO writes. How the CEO writes. Which conversations are already happening that an attacker might be able to insert themselves into.
Historically, that is incredibly valuable information, but there is a human cost to going through all of it.
Now you can classify it.
Instead of an attacker manually reading ten thousand messages trying to understand the company, a model can help answer much narrower questions.
Who has financial authority?
Which conversations involve payments?
Who does this person regularly trust?
Which identity would be useful to impersonate?
That does not fundamentally reinvent business email compromise. It makes the information gathered after compromise much easier to use.
The device-code phishing component is interesting for a similar reason because the victim can actually be interacting with Microsoft’s legitimate authentication infrastructure.
They are not necessarily typing their password into some terrible copy of a Microsoft login page hosted on a random domain.
They can authenticate normally. They can complete MFA. Microsoft can successfully verify that they are exactly who they claim to be.
The problem is what they authorized.
That distinction matters.
We sometimes reduce authentication security to “Do we have MFA?” when the actual system is more complicated than that. MFA can verify the identity of the person completing an authentication flow. It does not automatically mean that person understands what application, device, or session they are authorizing.
Again, the system established trust. The problem happened after that.
The Next.js vulnerability is a little different, but I think there is a related engineering lesson there too.
ImageResponse sounds harmless.
If somebody told me they were investigating a critical remote code execution vulnerability and then said the affected functionality generates Open Graph images, that would not be the first place I expected them to go.
But the server does not care whether we mentally categorize something as “just an image.”
It is still executing code.
It is still processing data.
And if attacker-controlled data reaches that processing path, it is part of your attack surface.
That is also why vulnerability scanners can only take you so far.
Knowing that you have an affected version of Next.js is important. Knowing whether your application actually uses the vulnerable Node.js ImageResponse implementation, where the input comes from, and whether an attacker can control that input is what tells you how the vulnerability relates to your environment.
The same principle applies well beyond Next.js.
A dependency inventory tells you what software exists.
It does not necessarily tell you how that software is being used.
Then there is Elastic Beanstalk Cluster Mode, which is almost the infrastructure version of the same abstraction problem.
AWS is taking something developers already understand as a PaaS experience and putting shared EKS infrastructure underneath it.
I actually like that direction.
I have spent enough of my career working with Kubernetes to know that most developers should not need to understand every detail of Kubernetes just to deploy an application.
A good platform should remove unnecessary complexity.
But abstraction does not make the underlying infrastructure stop existing.
If multiple applications are now sharing infrastructure, somebody still needs to understand what that means for isolation, resource contention, upgrades, capacity, and blast radius.
The developer experience can be:
“Here is my application. Please run it.”
That is great.
The platform engineering experience still has to include:
“What happens when the thing underneath all of these applications has a bad day?”
And that is probably the thread connecting most of this week’s stories for me.
We keep building better abstractions around infrastructure, authentication, dependencies, and developer workflows. That is generally a good thing. Engineers should not have to manually reason about every implementation detail every time they deploy an application or authenticate to a service.
But abstractions create boundaries where we can forget what is happening underneath them.
A valid token does not mean the person using it should still have it.
A successful MFA challenge does not mean the user intended to authorize that session.
An image-generation endpoint is not automatically harmless because its output is a PNG.
A managed platform running on Kubernetes does not eliminate Kubernetes failure modes.
And removing the thing that originally compromised you does not revoke everything the attacker may have already taken.
The abstraction can simplify the normal path.
You still need to understand the trust underneath it when the normal path breaks.
That is usually where the incident starts getting interesting.
📝 Notes
Show Notes
This week on Ship It Weekly: AWS introduced Elastic Beanstalk Cluster Mode, allowing multiple applications to run on shared EKS infrastructure while AWS handles much of the Kubernetes complexity. CrowdSec published how a software supply-chain compromise led to attackers copying roughly 170 private repositories using a stolen OAuth token. A critical Next.js vulnerability in ImageResponse can lead to remote code execution through attacker-controlled SVG data. And Microsoft disrupted EvilTokens, a cybercrime platform linked to more than 12,000 compromised inboxes across 10,000 organizations.
The bigger theme this week is what happens after trust has been established. Elastic Beanstalk Cluster Mode puts more infrastructure behind a managed abstraction, but shared infrastructure still means understanding isolation and blast radius. CrowdSec shows how an initial compromise can become a credential problem long after the malicious code is gone. Next.js shows how something as ordinary as generating a social preview image can expose a server-side execution path. And EvilTokens shows how attackers can use valid access to move faster once inside an account.
In the lightning round: F5 has a critical BIG-IP APM vulnerability under active exploitation. GitHub Enterprise Cloud can now export an inventory of credentials with enterprise access, including PATs, SSH keys, OAuth tokens, and GitHub App credentials. Zyxel patched a vulnerability affecting GS1900 switches. And Veeam Agent for Microsoft Windows has a privilege-escalation vulnerability that can lead to SYSTEM access.
And the human closer comes back to CrowdSec. Removing the malicious package, patching the server, or reimaging the workstation does not necessarily end the incident. If an attacker already stole an OAuth token, cloud credential, SSH key, session, or registry credential, that access can survive long after the original compromise is gone. Containment means understanding not only how the attacker got in, but what they took with them
The thing that stuck with me most this week is how many of these stories are really about trust. Not necessarily whether you trust AWS, GitHub, Microsoft, or a particular open-source project, but what happens after your systems have decided something is trusted.
That is where a lot of the interesting infrastructure and security problems seem to live now.
Take the CrowdSec incident. The initial compromise was in the software supply chain, but that was not really the end result the attacker cared about. The valuable part was the credential they were able to get from it. Once that OAuth token existed outside the environment where it belonged, fixing the original package did not fix the larger problem.
According to CrowdSec, that stolen token was eventually used to copy roughly 170 private GitHub repositories in about nine minutes.
Nine minutes.
That is not much of an incident-response window.
By the time somebody realizes something is wrong, starts a Slack thread, pulls in security, checks the logs, figures out which account is involved, and starts revoking access, the actual data movement may have been over for hours, days, or longer.
And I think that changes how we should think about containment.
We spend a lot of time talking about initial access. Patch the vulnerability. Remove the malicious package. Reimage the developer laptop. Kill the process.
Obviously you need to do all of those things.
But the question immediately after that should be: what could this thing authenticate to?
If it was a developer workstation, that answer might be GitHub, AWS, Kubernetes clusters, package registries, CI systems, internal tooling, databases, artifact repositories, or half a dozen other things.
Then you have another question: what credentials were actually present?
That sounds simple until you try answering it during a real incident.
Some credentials are short-lived. Some are not. Some are sitting in environment variables. Some are managed by credential helpers. Some are PATs somebody created two years ago. Some exist in CI. Some belong to GitHub Apps. Some are SSH keys. Some are sessions that are already authenticated.
That is why the GitHub credential inventory announcement in the lightning round is more useful than it might initially sound.
Being able to ask, “Show me the credentials capable of accessing this enterprise, who owns them, what they can access, when they expire, and when they were last used,” is useful on a normal Tuesday.
During an incident, it can become one of the first questions you need answered.
The EvilTokens story approaches the same problem from a different direction.
The part that interests me is not really “hackers are using AI.”
We have heard some version of that story enough times already.
The more interesting part is what AI becomes useful for once an attacker already has access.
A compromised mailbox can contain years of information. Thousands or tens of thousands of emails. Vendor conversations. Invoices. Org charts. Travel schedules. Internal projects. Who approves payments. Who reports to whom. Which vendors regularly ask for money. How the CFO writes. How the CEO writes. Which conversations are already happening that an attacker might be able to insert themselves into.
Historically, that is incredibly valuable information, but there is a human cost to going through all of it.
Now you can classify it.
Instead of an attacker manually reading ten thousand messages trying to understand the company, a model can help answer much narrower questions.
Who has financial authority?
Which conversations involve payments?
Who does this person regularly trust?
Which identity would be useful to impersonate?
That does not fundamentally reinvent business email compromise. It makes the information gathered after compromise much easier to use.
The device-code phishing component is interesting for a similar reason because the victim can actually be interacting with Microsoft’s legitimate authentication infrastructure.
They are not necessarily typing their password into some terrible copy of a Microsoft login page hosted on a random domain.
They can authenticate normally. They can complete MFA. Microsoft can successfully verify that they are exactly who they claim to be.
The problem is what they authorized.
That distinction matters.
We sometimes reduce authentication security to “Do we have MFA?” when the actual system is more complicated than that. MFA can verify the identity of the person completing an authentication flow. It does not automatically mean that person understands what application, device, or session they are authorizing.
Again, the system established trust. The problem happened after that.
The Next.js vulnerability is a little different, but I think there is a related engineering lesson there too.
ImageResponsesounds harmless.If somebody told me they were investigating a critical remote code execution vulnerability and then said the affected functionality generates Open Graph images, that would not be the first place I expected them to go.
But the server does not care whether we mentally categorize something as “just an image.”
It is still executing code.
It is still processing data.
And if attacker-controlled data reaches that processing path, it is part of your attack surface.
That is also why vulnerability scanners can only take you so far.
Knowing that you have an affected version of Next.js is important. Knowing whether your application actually uses the vulnerable Node.js
ImageResponseimplementation, where the input comes from, and whether an attacker can control that input is what tells you how the vulnerability relates to your environment.The same principle applies well beyond Next.js.
A dependency inventory tells you what software exists.
It does not necessarily tell you how that software is being used.
Then there is Elastic Beanstalk Cluster Mode, which is almost the infrastructure version of the same abstraction problem.
AWS is taking something developers already understand as a PaaS experience and putting shared EKS infrastructure underneath it.
I actually like that direction.
I have spent enough of my career working with Kubernetes to know that most developers should not need to understand every detail of Kubernetes just to deploy an application.
A good platform should remove unnecessary complexity.
But abstraction does not make the underlying infrastructure stop existing.
If multiple applications are now sharing infrastructure, somebody still needs to understand what that means for isolation, resource contention, upgrades, capacity, and blast radius.
The developer experience can be:
“Here is my application. Please run it.”
That is great.
The platform engineering experience still has to include:
“What happens when the thing underneath all of these applications has a bad day?”
And that is probably the thread connecting most of this week’s stories for me.
We keep building better abstractions around infrastructure, authentication, dependencies, and developer workflows. That is generally a good thing. Engineers should not have to manually reason about every implementation detail every time they deploy an application or authenticate to a service.
But abstractions create boundaries where we can forget what is happening underneath them.
A valid token does not mean the person using it should still have it.
A successful MFA challenge does not mean the user intended to authorize that session.
An image-generation endpoint is not automatically harmless because its output is a PNG.
A managed platform running on Kubernetes does not eliminate Kubernetes failure modes.
And removing the thing that originally compromised you does not revoke everything the attacker may have already taken.
The abstraction can simplify the normal path.
You still need to understand the trust underneath it when the normal path breaks.
That is usually where the incident starts getting interesting.