Skip to content

Conversation

@jmandel-via-jules
Copy link

📑 Summary

Add sandboxBaseUrl configuration option to enable relative URL resolution in sandbox mode.

When securityLevel: 'sandbox' is used, diagrams render inside data: URI iframes for security isolation. However, this breaks relative links (./page.html, #section) because data URIs have no base URL context. This PR adds an opt-in sandboxBaseUrl option that pre-resolves relative URLs to absolute URLs before embedding.

Example:

mermaid.initialize({
  securityLevel: 'sandbox',
  sandboxBaseUrl: window.location.href
});

📏 Design Decisions

Why this approach?

URLs are resolved directly on the live DOM before innerHTML extraction, rather than post-processing the serialized SVG string. This:

  • Avoids a DOMParser/XMLSerializer round-trip
  • Incurs zero overhead when sandboxBaseUrl is not set
  • Operates on the same trusted DOM tree Mermaid already constructed

URL handling behavior

URL Type Example Result
Relative ./page.html Resolved to absolute
Hash #section Resolved to absolute
Absolute https://... Unchanged
Special mailto:, javascript: Unchanged

Security

  • Opt-in only; default behavior unchanged
  • sandboxBaseUrl set by page author, not diagram content
  • Sandbox iframe isolation fully preserved
  • Uses browser-native URL constructor

📋 Tasks

Make sure you

  • 📖 have read the contribution guidelines
  • 💻 have added necessary unit/e2e tests.
  • 📓 have added documentation. Make sure MERMAID_RELEASE_VERSION is used for all new features.
  • 🦋 If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

… sandbox mode

When securityLevel is 'sandbox', diagrams are rendered inside a data: URI iframe.
Since data URIs have no base URL context, relative URLs in diagram links (e.g.,
"./page.html") cannot be resolved by the browser and fail to navigate.

This change adds a `sandboxBaseUrl` configuration option that, when provided,
pre-resolves all relative URLs in the rendered SVG to absolute URLs before
base64-encoding and embedding in the sandbox iframe.

Changes:
- Add `sandboxBaseUrl` to config schema and TypeScript types
- Create `resolveRelativeUrls` utility in `utils/sandboxUrl.ts`
- Integrate URL resolution into `putIntoIFrame` function
- Add comprehensive unit tests for the URL resolution logic

Example usage:
```javascript
mermaid.initialize({
  securityLevel: 'sandbox',
  sandboxBaseUrl: 'https://example.com/docs/',
  flowchart: { htmlLabels: false }
});
```
Improves performance by eliminating parse/serialize round-trip:
- Rename resolveRelativeUrls -> resolveRelativeUrlsInElement
- Operate directly on live DOM element instead of parsing SVG string
- Call URL resolution before innerHTML extraction in mermaidAPI
- Remove sandboxBaseUrl parameter from putIntoIFrame
- Update tests to work with DOM elements
@changeset-bot
Copy link

changeset-bot bot commented Nov 29, 2025

⚠️ No Changeset found

Latest commit: 496ac15

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@netlify
Copy link

netlify bot commented Nov 29, 2025

Deploy Preview for mermaid-js ready!

Name Link
🔨 Latest commit 496ac15
🔍 Latest deploy log https://app.netlify.com/projects/mermaid-js/deploys/692b4d9f4fc11700089473e2
😎 Deploy Preview https://deploy-preview-7203--mermaid-js.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 29, 2025

Open in StackBlitz

@mermaid-js/examples

npm i https://pkg.pr.new/mermaid-js/mermaid/@mermaid-js/examples@7203

mermaid

npm i https://pkg.pr.new/mermaid-js/mermaid@7203

@mermaid-js/layout-elk

npm i https://pkg.pr.new/mermaid-js/mermaid/@mermaid-js/layout-elk@7203

@mermaid-js/layout-tidy-tree

npm i https://pkg.pr.new/mermaid-js/mermaid/@mermaid-js/layout-tidy-tree@7203

@mermaid-js/mermaid-zenuml

npm i https://pkg.pr.new/mermaid-js/mermaid/@mermaid-js/mermaid-zenuml@7203

@mermaid-js/parser

npm i https://pkg.pr.new/mermaid-js/mermaid/@mermaid-js/parser@7203

@mermaid-js/tiny

npm i https://pkg.pr.new/mermaid-js/mermaid/@mermaid-js/tiny@7203

commit: 496ac15

@codecov
Copy link

codecov bot commented Nov 29, 2025

Codecov Report

❌ Patch coverage is 2.50000% with 39 lines in your changes missing coverage. Please review.
✅ Project coverage is 3.56%. Comparing base (614129c) to head (496ac15).

Files with missing lines Patch % Lines
packages/mermaid/src/utils/sandboxUrl.ts 2.85% 34 Missing ⚠️
packages/mermaid/src/mermaidAPI.ts 0.00% 5 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           develop   #7203      +/-   ##
==========================================
- Coverage     3.56%   3.56%   -0.01%     
==========================================
  Files          473     475       +2     
  Lines        47566   47616      +50     
  Branches       734     735       +1     
==========================================
+ Hits          1696    1697       +1     
- Misses       45870   45919      +49     
Flag Coverage Δ
unit 3.56% <2.50%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/mermaid/src/config.type.ts 100.00% <ø> (ø)
packages/mermaid/src/mermaidAPI.ts 0.29% <0.00%> (-0.01%) ⬇️
packages/mermaid/src/utils/sandboxUrl.ts 2.85% <2.85%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@argos-ci
Copy link

argos-ci bot commented Nov 29, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Nov 29, 2025, 7:56 PM

Replace innerHTML with DOM manipulation (createElement + textContent)
to prevent potential XSS attacks flagged by CodeQL.
Add tests for catch blocks when URL resolution fails with invalid base URL.
Prevent sandboxBaseUrl from being set via diagram directives, which
could allow attackers to redirect relative links to malicious domains.
@jmandel-via-jules jmandel-via-jules changed the title Claude/add sandbox base url 01 h hj4v fa3 g qc ug p cs jd qe9 t feat: add sandboxBaseUrl config to resolve relative URLs in sandbox mode Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants