Jellypod, Inc.

The Claude Code Changelog

TechnologyNews

Listen

All Episodes

Claude Code 2.1.113: Faster Launches, Safer Bash Rules

This episode breaks down a small-looking Claude Code update that swaps in a native binary for faster cold starts and a leaner CLI, especially in CI. It also digs into important Bash rule fixes, including a simple env bypass, dangerous find -exec/find -delete approvals, and tighter handling of macOS private paths.

This show was created with Jellypod, the AI Podcast Studio. Create your own podcast with Jellypod today.

Get Started

Is this your podcast and want to remove this banner? Click here.


Chapter 1

The tiny update that changes both speed and trust

Lachlan Reed

Welcome to the show — I’m Lachlan Reed here with James Turner, and James, I love updates that look like a flea and kick like a mule. Claude Code 2.1.113 sounds like a sleepy patch release, but it swaps the CLI from spawning bundled JavaScript to launching a native Claude Code binary. And not one giant blob, either — it ships as a per-platform optional npm dependency.

James Turner

[curious] That phrase — “per-platform optional npm dependency” — is the whole story. Instead of one universal JavaScript package hauling everything around, npm can pull the right binary for macOS, Linux, whatever box you’re on. That means the JS bundle gets smaller, and the startup path gets shorter because you’re not booting a JS runtime just to get to the tool.

Lachlan Reed

And startup pain is REAL. In local dev, a slow tool is annoying. In CI, where you might cold-start over and over, it’s like stepping in the same pothole all day. First run especially — if a command takes that extra beat, you feel it in your bones. I’ve had builds where the script was technically fine, but the toolchain woke up like an old trail bike in winter. [chuckles]

James Turner

[responds quickly] “Cold-start over and over” is exactly it. The concrete wins here are smaller JS bundle size and faster cold starts. And those aren’t abstract engineering trophies — listeners will feel them on first-run and in CI-heavy workflows where every second of startup latency gets multiplied.

Lachlan Reed

What’s funny is a native binary can sound like MORE moving parts. You hear “binary” and think, oh beauty, now we’ve got platform weirdness, maybe signing issues, maybe some gremlin in the shed. But here it actually reduces the runtime mess the CLI has to drag around.

James Turner

[skeptical] I think that tension is worth sitting on. Convenience versus control, right? JavaScript everywhere feels convenient because it’s one delivery shape. But a native binary per platform can be more controlled operationally. You can update those binaries independently instead of republishing one giant JS bundle that has to account for every environment at once.

Lachlan Reed

So the “tiny” release is really an architectural swap. Not flashy, but it changes the feeling of the tool. Less ballast, quicker launch, fewer runtime gymnastics. That’s the sort of patch note people skip — then suddenly the CLI feels snappier and they go, huh, that’s nicer.

James Turner

And trust matters too. A CLI that starts cleanly and predictably feels sturdier. Performance isn’t just speed; it’s confidence. If your tool spends less time doing invisible setup, there’s less mystery between you and the command you actually meant to run.

Chapter 2

The easiest Bash bypass was literally one word env

James Turner

[matter-of-fact] Now the security fix that made me wince: deny rules for Bash commands could be bypassed by wrapping the command in exec wrappers like env, sudo, watch, ionice, setsid, and similar helpers. The painfully simple version was just prepending one word: env.

Lachlan Reed

[questioning tone] And “one word” is the bit that sticks. Not some galaxy-brain exploit — just env. So if a deny rule was looking at the first token, it saw env instead of the thing actually being executed?

James Turner

Exactly. And that’s the key lesson: deny rules are only meaningful if they match the command as actually executed, not merely the first token the user typed. If your parser treats wrappers as harmless decoration, your security boundary is basically made of cardboard.

Lachlan Reed

[skeptical] I’m with you on the bug, but I wanna push a bit. Was this a serious bypass in practice, or one of those “technically true, edge-case weirdness” situations? Because sometimes users assume these rules are magic force fields when they were really more like guardrails.

James Turner

No, I’d call this serious — especially in CI or any broad-permission setup. If a team believed a deny rule blocked a class of Bash commands, and that block could be sidestepped with env or sudo or watch, then the protection was weaker than the policy implied. In a locked-down environment, “we thought this was denied” is not a small misunderstanding.

Lachlan Reed

CI is the bit that changes it for me. Because in a local shell, maybe you catch weird behavior. In automation, stuff just runs. And if the rule says no, people assume NO, not “no unless you dress it up in a different jacket.”

James Turner

[sharp] Right — “dress it up in a different jacket” is perfect. Wrappers don’t change the underlying intent. They just alter how the command is invoked. Security tooling has to see through that layer.

Lachlan Reed

Also, let’s be honest, env looks harmless. It’s practically beige. You see env and think environment variables, no drama. But if env becomes a tunnel under the deny rule, that’s a nasty little gap.

James Turner

And now that gap is closed. Which is good, because the simplest bypasses are usually the ones that get used. Nobody forgets a one-word workaround.

Chapter 3

Find was never just find

Lachlan Reed

I had a very specific reaction to this next fix, because my first instinct was, “find is fine.” Read-only vibe. Harmless little bloodhound sniffing through files. But the `Bash(find:*)` allow-rule fix closes a loophole where `find -exec` and `find -delete` were being auto-approved just because the base command was `find`.

James Turner

[leans in] And those two flags are the whole problem. `find -exec` can run arbitrary commands. `find -delete` can remove files. So approving plain `find` should NEVER have implied permission for either of those behaviors.

Lachlan Reed

`-exec` is the one that changes the personality of the tool. That’s not searching anymore — that’s outsourcing action. “Find these files, then do whatever I say.” That’s a different beast.

James Turner

[responds quickly] Yes. This is where security bugs hide: in the gap between “looks harmless” and “has side effects.” A rule that keys off the command name alone misses the semantic jump from inspection to execution. Same binary, totally different risk profile.

Lachlan Reed

Let me try to explain it back. If I allow `find`, I probably mean, “you can look around.” I do NOT mean, “and while you’re at it, run arbitrary commands with `-exec` or start deleting things with `-delete`.” Almost like allowing a torch and accidentally allowing a flamethrower because, eh, both make fire.

James Turner

[laughs] Slightly dramatic, but yes. The permission should map to behavior, not just branding. `find` is not one capability. It’s a command with modes, and some modes cross directly into side effects.

Lachlan Reed

This one feels especially real because loads of devs trust `find` on instinct. I do. You type it when you’re poking around a repo, looking for config files, cleaning up some mystery directory. Then `-delete` wanders in and suddenly your “just having a look” command is carrying a chainsaw.

James Turner

And the fix matters because it restores that intuition properly. Plain `find` can be treated differently from `find` with dangerous flags. That’s better security, but also better mental models for users. You shouldn’t have to remember that a read-looking command secretly inherited write-like approval.

Chapter 4

macOS private paths and the gap it finally closes

James Turner

[calm] Last one, and it’s a classic filesystem gotcha. On macOS, `/etc` is really a symlink to `/private/etc`. Same story for `/var`, `/tmp`, and `/home`. In 2.1.113, `/private/etc`, `/private/var`, `/private/tmp`, and `/private/home` are now treated as dangerous removal targets under `Bash(rm:*)` rules.

Lachlan Reed

The token there is `/private/etc`. Because if your rule protected the pretty path — `/etc` — but not the real target under it, then someone could bypass the protection just by aiming at `/private/etc` instead. Same destination, different sign on the road.

James Turner

Exactly. And this wasn’t theoretical. The filesystem path resolution created a gap between the human-readable rule and the actual destructive target. Humans think in the friendly path. The system follows the symlink. If your rule engine only respected the friendly version, `rm` protections had a hole in them.

Lachlan Reed

[reflective] That’s such a macOS little trick, isn’t it? Like the house has a nice front door and then a secret service entrance around the back. And the important detail is this fix is for `rm` allow rules specifically. Read operations are unaffected.

James Turner

Right — that distinction matters. It tightens destructive actions without making ordinary inspection workflows more painful. So you’re not broadly punishing reads; you’re being stricter where the blast radius is file removal.

Lachlan Reed

Which, honestly, is how you want these fixes done. Don’t make everyone’s day worse. Just stop the foot-gun from firing through the floorboards. If I’m reading a file in `/private/etc`, fine. If I’m removing stuff there under a rule that was supposed to protect `/etc`... yeah, nah.

James Turner

[softly] And this leaves teams with a slightly uncomfortable question. If your current rules only protect the pretty path, not the real one underneath, how many other “safe” assumptions in your automation are only symlink-deep?

Lachlan Reed

That’s the bit to sit with. Tiny version number, big trust audit. [short pause] Catch you next time.

James Turner

See you then.