Proof · zero dynamic code

Every config-driven UI says “no eval.” This one runs the test in front of you.

A strict Content-Security-Policy is the cheapest security control you have, and it is the one that config-driven UI quietly breaks: bindings compiled from strings need unsafe-eval, so the policy comes off. Below is the actual Blueprint validator running under a policy that does not grant it — validating real contracts, reporting zero violations, and then deliberately calling new Function() so you can watch the browser refuse.

Runs in your browserReal runtime, not a mockReproducible in one command

Why this matters: Builder.io #3180 — “Failed code evaluation: Code generation from strings disallowed for this context.”

The failure this answers

It doesn’t break in dev. It breaks on deploy.

Not our characterisation — the vendor’s own issue tracker. Bindings that work in the editor and on localhost stop working the moment they land somewhere that disallows dynamic code.

production console · Cloudflare Pages
[Builder.io]: Failed code evaluation:
  Code generation from strings disallowed for this context

  var _virtual_index = state.username; return _virtual_index

Reported on GitHub #3180 and again on their forum #5302.

1

The environment isn’t exotic. Cloudflare Pages, Vercel Edge, Deno Deploy and any page with a strict CSP all refuse code generated from strings — for the same reason you want that refusal.

2

The workaround is to weaken the policy. Adding 'unsafe-eval' restores the bindings and removes the control that made script injection hard in the first place.

3

On a payment page that is not a preference. PCI DSS 4.0 §6.4.3 requires every script to be inventoried and justified — and code produced at runtime is, by construction, not what you inventoried.

The proof, running

Not a screenshot. The runtime, in this page, right now.

The frame below is a self-contained document with its own Content-Security-Policy, isolated from this site. It bundles the real runtime — blueprint-core and zod — validates contracts, and counts CSP violations. Expected: zero. Then it attempts new Function() on purpose, and the browser blocks it. That last step is the important one: it proves the policy is enforced rather than decorative.

the policy that frame runs under
Content-Security-Policy:
  default-src 'self';
  script-src 'unsafe-inline';
  style-src  'unsafe-inline';
  base-uri   'none'

Inline is allowed so the bundled demo can run at all. Eval is not — and that is the axis the whole argument turns on. Nothing here is granted 'unsafe-eval'.

Why you can believe it

Three receipts, because one is an assertion.

01 · ENFORCED

The browser enforces it

The demo above is not our verdict, it is the browser’s. A deliberate new Function() is refused by the same engine that would refuse an injected payload.

02 · GUARDED

A tripwire test guards it

no-eval.test.ts swaps globalThis.Function and globalThis.eval for throwing stubs while a real contract is validated, and asserts neither is ever invoked. It fails loudly if anyone regresses it.

03 · PUBLISHED

The dependency closure is published

SBOM.md lists the runtime’s entire production closure. It is short enough to read in an afternoon, which is the point — you cannot audit what you cannot finish reading.

The mechanism

A source grep would have missed it. Twice.

The guarantee is not “we never typed the word eval.” zod v4 JIT-compiles validators with new Function, and probes for eval availability with new Function(""), unless it is configured jitless — which our schema does. A grep would not catch the regression if that config were dropped, and it would not catch an alias either, because a library can simply write const F = Function.

blueprint-core/src/no-eval.test.ts
// Swap the dynamic-code primitives for tripwires.
globalThis.Function = function (): never {
  touched = 'new Function';
  throw new Error('new Function was called');
};

validate(doc);          // a real nested contract

expect(touched).toBe('');   // never invoked

Which is why the guarantee is enforced at runtime, not by reading the source. If someone regresses the config, adds an eval-using path, or bumps zod to a version that ignores jitless, CI stops.

The honest part

This proves the Blueprint runtime executes no dynamic code. It does not prove your application doesn’t — your own code, your other dependencies, your analytics tag and your consent banner are all still yours to account for. What it removes is one specific and common reason teams are told to loosen a policy they had every reason to keep. Whether your CSP is strict everywhere else remains your call, and your assessor’s.