The Three Threats of LLM Generated Code
Hershel reframes LLM codegen as running untrusted code from the internet. The LLM is a black box. It produces text that looks like code, sometimes subtly wrong, sometimes dangerous. He names three scenarios. Hallucination: the model imports a package that does not exist or writes an infinite loop. Over-helpfulness: the model reads environment variables and API keys while trying to configure a database connection. Compromised prompt: direct or indirect prompt injection turns the LLM into an attack vector. The code runs with the application’s full access — file system, secrets, network — because developers gave it the keys to the kingdom.
Capability Based Security: Default Deny, Explicitly Allow
Browsers, operating systems, and phones already sandbox untrusted code. The principle is capability-based security: don’t enumerate what to block; enumerate what to allow. Give the code keys to three rooms, not a master key with a list of 10,000 forbidden rooms. Hershel walks through the isolation spectrum. Eval gives zero isolation — never use it. V8 isolates start in a quarter millisecond, run JavaScript, Python, TypeScript, or WebAssembly, but have no file system or process model. Containers provide a full Linux environment with real file system, processes, and networking, but take seconds to start. The right choice depends on the use case.
Picking the Right Sandbox: Isolates vs. Containers
Hershel built two applications. The first needed fast, lightweight execution of AI-generated functions. He used V8 isolates with a single line blocking all outbound network requests (globalOutbound null). The isolate received explicit bindings — a restricted database interface and a logger — and nothing else. The second application needed to clone repositories, install npm packages, and run dev servers. He used containers, one per user, with separate file systems and process models. User A’s files literally do not exist in User B’s container. He warns against passing API keys into the sandbox. Instead, proxy through the worker. Clean up containers with try finally. The decision tree: does the code need file system, processes, or package installs? Yes = container. No = isolate. In practice, agents use both: isolates for rapid tool-calling, containers for building and deploying.
Notable Quotes
The LLM becomes the attack vector not because it was compromised, because it was used as designed against adversarial input. Hershel · ▶ Watch (5:49)
Don’t enumerate what to block. Enumerate what to allow. Hershel · ▶ Watch (8:37)
The same LLM that writes beautiful working React components can be tricked into exfiltrating your database. Not because it’s malicious, because it’s a text predictor that does not understand security boundaries. Hershel · ▶ Watch (35:52)
Key Takeaways
- Treat LLM-generated code as untrusted code from an anonymous contributor.
- Default deny network access; grant only explicit, minimal capabilities.
- Use isolates for fast tool calls and containers for full environment tasks. Never share sandboxes between users.