Found in safe-bash deep pentest (v3), browser surface pass. Verified with executed PoCs against the real built dist/browser.js bundle on Node 22.
Severity: Low (informational) — documentation/dead-code drift; not exploitable (boundedness verified)
Summary
The README/threat-model note states the browser entry's [[ … =~ … ]] "explicitly returns status 2". Actual behavior: dist/browser.js runs [[ foo =~ f ]] → status 0 — regex executes in-thread. Root cause: src/shell/runtime.ts was refactored to use compileEre/matchEre directly with an EreLedger; nothing imports ere/transport/root.js anymore (zero non-test importers), so the fail-closed override browser/regex.mjs and its esbuild alias (scripts/bundle-safe-bash.mjs:25-28) are dead code. The regex worker is confirmed unreachable from the browser bundle (grep -c "new Worker\|worker_threads" dist/browser.js → 0). Boundedness verified: hostile [[ aaaa…! =~ (a+)+b ]] → status 3, "ERE profile limit exceeded: states (65536)" in 49 ms; abort signal honored. Threats (b)/(d) not exploitable.
Location
packages/safe-bash/src/browser.ts:19 — exports regex-execution/public
packages/safe-bash/browser/regex.mjs:1-8 — override that throws ConditionalUnsupported (dead)
packages/safe-bash/scripts/bundle-safe-bash.mjs:25-28 — alias ere/transport/root.js → browser/regex.mjs (inert)
packages/safe-bash/src/shell/runtime.ts:1113-1129 — in-thread ERE with EreLedger
Suggested fix
Update the docs/threat-model note ([[ =~ ]] is now in-thread, ledger-bounded, statuses 0/1/2/3), and either delete browser/regex.mjs + the dead alias or add a build-time assertion that the browser bundle contains no worker transport, since the fail-closed alias no longer fires.
Status: NEW
Found in safe-bash deep pentest (v3), browser surface pass. Verified with executed PoCs against the real built
dist/browser.jsbundle on Node 22.Severity: Low (informational) — documentation/dead-code drift; not exploitable (boundedness verified)
Summary
The README/threat-model note states the browser entry's
[[ … =~ … ]]"explicitly returns status 2". Actual behavior:dist/browser.jsruns[[ foo =~ f ]]→ status 0 — regex executes in-thread. Root cause:src/shell/runtime.tswas refactored to usecompileEre/matchEredirectly with anEreLedger; nothing importsere/transport/root.jsanymore (zero non-test importers), so the fail-closed overridebrowser/regex.mjsand its esbuild alias (scripts/bundle-safe-bash.mjs:25-28) are dead code. The regex worker is confirmed unreachable from the browser bundle (grep -c "new Worker\|worker_threads" dist/browser.js→ 0). Boundedness verified: hostile[[ aaaa…! =~ (a+)+b ]]→ status 3,"ERE profile limit exceeded: states (65536)"in 49 ms; abort signal honored. Threats (b)/(d) not exploitable.Location
packages/safe-bash/src/browser.ts:19— exports regex-execution/publicpackages/safe-bash/browser/regex.mjs:1-8— override that throwsConditionalUnsupported(dead)packages/safe-bash/scripts/bundle-safe-bash.mjs:25-28— aliasere/transport/root.js→browser/regex.mjs(inert)packages/safe-bash/src/shell/runtime.ts:1113-1129— in-thread ERE withEreLedgerSuggested fix
Update the docs/threat-model note (
[[ =~ ]]is now in-thread, ledger-bounded, statuses 0/1/2/3), and either deletebrowser/regex.mjs+ the dead alias or add a build-time assertion that the browser bundle contains no worker transport, since the fail-closed alias no longer fires.Status: NEW