The Snyk Wars: A License to Snyk Is Not a Security Program Monday, 9:14 AM — The Pentest Report Lands The…

David L. — Director - Information Security and Technical Operations

The Snyk Wars: A License to Snyk Is Not a Security Program

Monday, 9:14 AM — The Pentest Report Lands

The security firm delivers its findings. Three of them sit in the particular shade of deep, bold red reserved for "drop what you are doing and stop reading email":

An unauthenticated attacker can achieve remote code execution via the message-routing service's transform endpoint by submitting arbitrary Groovy scripts over a single HTTP request.

A default test/test account carries platform_admin privileges in the identity provider.

A SQL injection point, running as the svc_ingest database account, can read every schema on the server — including the credential store — enabling full platform account takeover.

Below them, in the calmer general red reserved for "high, but you may finish your coffee first," sits a fourth:

One microservice accepts authentication tokens from another without verifying the audience claim, trusting a signature that was never meant for it.

The first finding is the one everyone reads out loud. No login. No token. Just a stranger on the internet politely handing your server a script and your server saying "sounds good, executing that now."

Monday, 11:47 AM — The VP Responds

The VP of Engineering reads the report, or at least the first paragraph of it, and issues the sentence that will haunt the next four business days:

"These aren't net-new. We already scan for vulnerabilities. We have Snyk."

He does not say the findings are wrong. He does not say they are right. He says they are already handled, which is a different claim entirely, and the one he will return to no matter what is put in front of him. A hush falls over the security channel. Somewhere, a penetration tester feels a disturbance in the force and doesn't know why.

Monday, 2:30 PM — The First Attempt at Explanation

The security engineer, still optimistic, tries the gentle approach. He explains that Snyk does two things, both of them useful, neither of them this.

Software Composition Analysis checks whether your third-party dependencies have known CVEs — it compares your package versions against a big public list of "libraries that turned out to be a mistake." Static Application Security Testing reads your source code looking for suspicious patterns, like SQL queries built out of string concatenation, ancient cryptography, or the developer who committed a password with a comment that says // TODO: remove before prod.

Both tools, he explains, read the code as written. Neither tool has ever seen the application as deployed. They answer "does this codebase contain scary patterns?" They do not answer "can a bored teenager in another timezone own this box?"

The VP nods thoughtfully and says, "Right, so Snyk would catch it."

Tuesday, 8:05 AM — The Groovy Problem, Explained Slowly

The security engineer comes in early, coffee in hand, prepared to die on this hill.

He explains why Snyk will never, ever flag the Groovy RCE. There is no CVE in the Groovy library — Groovy is working perfectly. There is no insecure code pattern in the transform endpoint's source, because that endpoint is supposed to execute scripts. That is its entire personality. The code is doing exactly what it was written to do.

The vulnerability isn't in the code. The vulnerability is that this script-executing endpoint has no authentication and is reachable from the public internet — which is a deployment decision, a routing rule, and an architectural assumption about network segmentation, none of which live in any file Snyk has ever read.

"So," says the VP, "we should tell Snyk to scan the routing."

The security engineer looks out the window for a long moment.

Tuesday, 3:15 PM — Reinforcements Arrive

A senior engineer, sensing blood in the water, joins the thread with examples, hoping volume will succeed where precision failed.

The alg:none situation. Whether an endpoint actually demands a valid token at runtime depends on middleware config, proxy routing, and the order of the filter chain — not on whether someone wrote @RequiresAuth above the function. Your JWT library can be flawless and still be configured to cheerfully accept tokens signed with the algorithm "none," which is cryptography's way of saying "I trust you, stranger."

The Keycloak thing. There is a realm with a test/test account that carries platform_admin privileges. This lives in a database, not in source code. No static scanner has ever peered into a live Keycloak realm export and gasped. It cannot. It doesn't know the realm exists.

The trust-boundary thing. Service A accepts JWTs issued by Service B without checking the audience claim. Neither service's code is individually wrong. Both engineers did their jobs correctly. The flaw lives in the handshake between them, in the space no single file describes.

The VP does not engage with any of the three. He replies: "This all sounds like stuff a scanner should catch," and lets the thread go quiet, which he has learned is the most efficient way to make a thread stop.

Wednesday, 10:00 AM — The Blast Radius Discourse

Someone escalates to the database example, believing impact will land where mechanism did not.

A static scanner finds SQL injection and says, helpfully, "this query concatenates user input." Technically true. Emotionally hollow.

The pentest says something with considerably more texture: this injection point, running as the svc_ingest database account, can read all 25 schemas on the server — including the Keycloak credential store — enabling full platform account takeover.

The difference, the engineer explains, is that Snyk tells you the door is unlocked. The pentest tells you the door is unlocked, leads to the vault, and the vault contains the keys to every other door in the building. Blast radius is invisible to static analysis, because static analysis has never once walked through the door it's warning you about.

The VP asks whether the SQL injection is "the same one Snyk already flagged last quarter." It was not. Snyk had flagged a different string concatenation, in an unrelated service, that turned out to be unreachable. He does not withdraw the question or acknowledge the answer. He simply moves on, the finding still un-acknowledged, now slightly older.

Wednesday, 2:00 PM — The Structural Problem, In Case the Technical One Wasn't Enough

Here is the part the security engineer already knows and dreads.

He cannot fix any of this himself, and he cannot make anyone else fix it either. He has no permission to create tickets in the development team's lane — the board where work actually becomes work is owned by engineering, and security is a guest with read access and opinions. His only instruments are the ones that require other people to choose to act: he can write findings, he can share findings, and he can call meetings about findings.

So he calls a meeting.

Wednesday, 4:44 PM — The Philosophical Turn

In the meeting, the security engineer identifies the exact logical error, isolates it, and holds it up to the light:

The VP keeps confusing "we scan for this category of issue" with "we have confirmed this specific system is not vulnerable."

Owning a SQL injection scanner is not the same as having parameterized queries on every endpoint. Owning a JWT library is not the same as having JWT validation correctly configured on every microservice. Having a fire alarm is not the same as the building not being on fire. The alarm is great. The building is, at this moment, on fire.

The VP listens, waits for him to finish, and says, "I hear you, but I think we're covered here." He does not say by what. "Covered" is doing the same work "handled" did on Monday: it sounds like a conclusion and commits to nothing.

Thursday, 9:30 AM — The Correct Mental Model, Delivered With The Last Reserves Of Patience

Thursday morning, the security team produces the framing they should have led with, before hope was a casualty.

The two things are complementary, not overlapping. SAST and SCA catch issues early, cheaply, and at enormous scale across the entire codebase — they stop known bad patterns from ever reaching production. That's a quality gate, and it's genuinely valuable and nobody is proposing you cancel the Snyk contract.

Penetration testing validates that the fully assembled system — its configuration, its deployment topology, its live authentication stack, its cross-service gossip — is actually secure as it runs in the real world. That's not a quality gate. That's a proof of exploitability.

One tool asks "is the recipe safe?" The other tool eats the meal and reports whether it survived.

Thursday, 11:52 AM — The Meeting That Was Supposed to Matter

Out of levers, the security engineer does the only thing left: he escalates. He gets the finding onto the CTO's calendar, presents all four items cleanly, and states the risk in plain language — unauthenticated remote code execution, reachable from the public internet, confirmed and reproducible.

The CTO is not technical. This is not a secret and not, by itself, a crime; plenty of good CTOs aren't. The problem is what fills the vacuum where technical judgment would otherwise go. In the absence of the ability to evaluate the claim on its merits, the CTO evaluates it on its acoustics: who spoke most confidently, who spoke last, and which path costs the least and disturbs the roadmap least. Security features that customers can see move resources. Everything else is a cost center asking for money to prevent a thing that hasn't happened yet.

The VP speaks last. He is calm, he is brief, and he is reassuring in exactly the register the CTO is tuned to receive. "We already scan for this. Snyk covers it. There's no new work here and nothing customer-facing at risk." Every one of those clauses is either false or beside the point, and every one of them is precisely what the CTO wants to be true.

The CTO nods. "Sounds like it's handled. Let's keep the team focused on the release." And with that, the loudest, last, and cheapest account of reality becomes the official one.

Thursday, 4:00 PM — "Resolution"

There is no resolution. That is the resolution.

The VP never acknowledged the findings — not once, across four days. He never said they were real and he never said they were wrong; he said they were handled, covered, and not net-new, three phrases that share the useful property of sounding like decisions while committing to nothing and creating no work. The findings were never disputed on the merits because they were never engaged on the merits.

No ticket is created, because the one person who understands the risk has no authority to create one in the lane where it would matter, and the people who have that authority were just told by their CTO to stay focused on the release. The security engineer files what he can — a record in his own team's backlog, a column no developer reads, where a Critical finding sits with all the compelling force of a sticky note left on someone else's desk.

The Quiet Part

This is the failure mode that never shows up in a breach postmortem, because it happens before the breach, in a calendar of small non-decisions.

Nobody said "we accept this risk," which would at least be a documented, signed, defensible choice. Nobody said "this is wrong, here's why." What happened instead was worse and more common: confident non-answers from the one person incentivized to make the problem quiet, blind deference from the one person with the authority to make it loud, and an org chart in which the only person who understood the finding was the only person with no power to act on it.

This is what a security program with no teeth looks like from the inside. Not a villain, not a cover-up — just a tooling license, a quarterly scan, a wall of green dashboards, and an organizational reflex to treat "we bought the thing" as "we did the work." The dashboards are real. The coverage they imply is not. A license to Snyk is a receipt, not a security program, and a receipt has never once stopped an attacker at the door.

The confirmed, reproducible, unauthenticated remote code execution remains exactly as exploitable as it was on Monday morning. The only artifacts the four-day argument produced are a meeting invite, a Slack thread, a finding rotting in the wrong backlog, and a decision-maker who is genuinely under the impression the matter is closed. In the language of the org, it is. In the language of the internet, the door is still open.

Snyk, blameless throughout, continues doing its actual job perfectly, having never once claimed to do the other one. The transform endpoint continues doing its job perfectly too — executing whatever it's handed, to anyone who asks, indefinitely, while three layers of management agree there is nothing here worth stopping the release for.

1 reactions · 0 comments

Read and join the discussion on Cyberr