Conversation
…embeds
- Strip underscore emphasis in heading IDs per CommonMark rules
(punctuation boundaries, adjacent runs, em+strong) so generated
anchors match GitHub's; intraword underscores are kept.
- Backslash-escape `_`/`*` in the internal `{#id ...}` attribute block
(markdown-it / markdown_yo) so IDs containing emphasis markers
survive inline parsing intact and rendered heading IDs always match
TOC anchors. Pandoc is excluded as it parses attributes natively.
- Fix line-level `![[note^block-id]]` embeds: prepend the `#` that
downstream block-transclusion handling expects.
- Dedupe @import/image hash extraction; minor cleanups.
- Tests: GitHub-parity ID cases, end-to-end heading-emphasis rendering
(no attr-block leak, TOC/anchor consistency, markdown_yo), and a
line-level bare block-ref embed test.
Refs:
- shd101wyy/vscode-markdown-preview-enhanced#2319
- shd101wyy/vscode-markdown-preview-enhanced#2317
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`.crossnote/config.js` and `.crossnote/parser.js` were evaluated with
`vm.runInNewContext()` (desktop) and `sval` (web), neither of which is a
security boundary: both share the host realm's object prototypes, so
untrusted workspace code could climb `({}).constructor.constructor` to the
host Function constructor and reach `process` / `child_process`, achieving
RCE just by opening a markdown file in a malicious repo (GHSA-427h-jhpr-8jch).
- Evaluate both files inside a QuickJS engine compiled to WebAssembly
(src/lib/js-sandbox.ts). The guest has its own realm/intrinsics and heap in
WASM memory; the host process/Function do not exist there, so the
prototype-chain escape has nothing to reach. Only plain data (config.js) and
strings (parser.js hooks) cross the boundary. A memory limit and an
execution-time deadline guard against DoS. Same sandbox runs in Node and the
browser/VS Code web extension (singlefile variant, WASM embedded as base64).
- Strip security-sensitive keys (enableScriptExecution, chromePath, pandocPath,
imageMagickPath, markdownYoBinaryPath) from an untrusted config.js result so
it cannot grant itself trust or point an executable path at an arbitrary
binary — these are only honoured from trusted editor settings.
- Remove the vm/sval-based interpretJS and the obsolete sanitizeParserConfig;
swap the `sval` dependency for quickjs-emscripten-core + singlefile variant.
- Add regression tests: RCE blocked at eval and in hooks, no host globals, DoS
timeout, sensitive-key stripping, and that normal hooks/config still work.
Thanks to @ritikchaddha for reporting the issue.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pnpm/action-setup@v4 runs on the deprecated Node.js 20 actions runtime; v6 runs on Node.js 24. The action is invoked with no `version` input and resolves pnpm from the package.json `packageManager` field, which v6 supports identically — no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Release
0.9.30. Bundles one security fix and two rendering/resolution bug fixes.🔒 Security — RCE in
.crossnote/config.js/.crossnote/parser.js(GHSA-427h-jhpr-8jch)These workspace files were evaluated with
vm.runInNewContext()(desktop) andsval(web). Neither is a security boundary — both share the host realm's object prototypes, so untrusted code could climb({}).constructor.constructorto reach the hostFunctionconstructor and, from there,process/child_process, achieving arbitrary command execution just by opening a markdown file in a malicious repository (no further interaction).Fix: both files are now evaluated inside a QuickJS engine compiled to WebAssembly (
src/lib/js-sandbox.ts). The guest has its own realm/intrinsics and heap in WASM memory; the hostprocess/Functiondo not exist there, so the prototype-chain escape has nothing to reach. Only plain data (config.js) and strings (parser.jshooks) cross the boundary. A memory limit and an execution-time deadline guard against DoS. The same sandbox runs in both Node and the browser/VS Code web extension (singlefile variant, WASM embedded as base64 — no dynamic import or asset fetch).Additionally, security-sensitive keys (
enableScriptExecution,chromePath,pandocPath,imageMagickPath,markdownYoBinaryPath) are stripped from an untrustedconfig.jsresult so a repo cannot grant itself trust or point an executable path at an arbitrary binary — these are only honoured from trusted editor settings.vm/sval-basedinterpretJSand the obsoletesanitizeParserConfig; swaps thesvaldependency forquickjs-emscripten-core+ the singlefile variant.config.jsmust return plain data (stray functions in its result are dropped).parser.jshooks are unaffected (string→string).Thanks to @ritikchaddha for reporting the issue.
🐛 Heading auto-ID for underscore emphasis (vscode-mpe#2319)
Headings using underscore emphasis (
# _Toy Story_,# __Bold Title__) produced IDs that retained the underscores, which markdown-it then re-interpreted as emphasis — splitting the internal{#id data-source-line}block and leaking it into the output. IDs now strip emphasis markers per CommonMark rules (matching GitHub's anchors), and IDs embedded in the{#id}block are backslash-escaped so rendered IDs always match TOC anchors.🐛
@import/![[wikilink]]resolution with#in the path (vscode-mpe#2317)When a directory name contains
#(e.g.[#11111111]), the#was mistaken for a heading-anchor fragment separator, breaking file resolution. The fragment is now extracted from the original import syntax before path resolution. Also fixes line-level![[note^block-id]]embeds (bare block ref without#).Testing
pandocinstalled locally; the only failures otherwise are environmentalspawn pandoc ENOENT).#-in-path resolution, bare block-ref embed.tsc --noEmitclean,eslintclean.build.jsexits 0 (CJS + neutral ESM + webview); ESM browser-safety guard passes; quickjs deps externalized; Node runtime smoke test works; the sandbox bundles cleanly forplatform: browserwith node builtins externalized and WASM base64-inlined (no fetch).🤖 Generated with Claude Code