Follow-up to #173, which moved the MIDI-sequencer compileSong path into a QuickJS WebAssembly sandbox (midisequencer/quickjssandbox.js).
Remaining unsafe path
The legacy pattern-sequencer mode (SONG_MODE_WASM, used by AssemblyScript-synth songs with generatePatterns() / generateInstrumentPatternLists()) still executes song source with full page privileges in editorcontroller.js:
const songfunc = new Function(
['global'].concat(Object.keys(patternToolsGlobal)),
songsource);
songfunc.apply(patternToolsGlobal, ...);
A malicious legacy-format song loaded from a shared repo (?gitrepo=) can therefore still reach fetch, localStorage, OPFS, etc. — the same threat #173 closed for MIDI-sequencer songs. The Node CLI render path (synth1/index.js line 24, plain eval) has the same shape.
Suggested approach
Same technique as #173: run the pattern_tools.js runtime plus the song source inside the QuickJS guest (the runtime is pure JS), return the generated patterns/instrument-pattern-lists/instrument defs as a JSON snapshot, and rehydrate patternToolsGlobal on the host. quickjssandbox.js already contains the guest build/run/timeout/memory-limit machinery — it mainly needs a second guest profile (pattern-tools runtime instead of the midisequencer runtime).
Also still native (lower priority, related)
- Embeddable songcompiler bundle and players export
compileSongUnsafe as compileSong (sandbox is tree-shaken out) — pianorolldemo/NFT players still compile natively.
- Media URL allowlist: the sandbox records
addAudio/addVideo/addImage specs and the host replays them — the natural chokepoint to restrict media to repo-relative URLs is not yet enforced.
🤖 Generated with Claude Code
Follow-up to #173, which moved the MIDI-sequencer
compileSongpath into a QuickJS WebAssembly sandbox (midisequencer/quickjssandbox.js).Remaining unsafe path
The legacy pattern-sequencer mode (
SONG_MODE_WASM, used by AssemblyScript-synth songs withgeneratePatterns()/generateInstrumentPatternLists()) still executes song source with full page privileges ineditorcontroller.js:A malicious legacy-format song loaded from a shared repo (
?gitrepo=) can therefore still reachfetch,localStorage, OPFS, etc. — the same threat #173 closed for MIDI-sequencer songs. The Node CLI render path (synth1/index.jsline 24, plaineval) has the same shape.Suggested approach
Same technique as #173: run the
pattern_tools.jsruntime plus the song source inside the QuickJS guest (the runtime is pure JS), return the generated patterns/instrument-pattern-lists/instrument defs as a JSON snapshot, and rehydratepatternToolsGlobalon the host.quickjssandbox.jsalready contains the guest build/run/timeout/memory-limit machinery — it mainly needs a second guest profile (pattern-tools runtime instead of the midisequencer runtime).Also still native (lower priority, related)
compileSongUnsafe as compileSong(sandbox is tree-shaken out) — pianorolldemo/NFT players still compile natively.addAudio/addVideo/addImagespecs and the host replays them — the natural chokepoint to restrict media to repo-relative URLs is not yet enforced.🤖 Generated with Claude Code