Web Viewer: data: and blob: subframe navigations are cancelled, breaking embedded web apps

Steps to reproduce

A. Minimal reproduction (no specific website involved)

  1. Enable the core Web Viewer plugin.
  2. Open https://example.com in Web Viewer.
  3. Open the developer console for that Web Viewer page and run:
(() => {
  const iframe = document.createElement("iframe");
  iframe.onload = () => console.log("data: LOAD OK");
  iframe.src = "data:text/html,<h1>TEST</h1>";
  document.body.appendChild(iframe);
  setTimeout(() => {
    if (iframe.isConnected) console.log("data: TIMEOUT");
  }, 3000);
})();
  1. Repeat the same test with other subframe sources for comparison: https:, about:blank, srcdoc, and a blob: URL created with URL.createObjectURL().

Observed in this test: https:, about:blank, and srcdoc load, while data: and blob: do not fire the load event and the frame content stays on about:blank.

B. Real-world example: Muse Spaces

  1. Open https://muse.ai in Web Viewer and sign in.
  2. Open any Space.
  3. The normal Muse chat UI works, but the Space content itself never appears.

The same Space renders correctly in Microsoft Edge, Vivaldi, and a smartphone browser.

Did you read and follow the Troubleshooting Guide?

Yes.

The issue was also tested with all browser extensions disabled and with Web Viewer’s built-in ad blocking disabled, with no change. The minimal reproduction above shows the problem is not specific to Muse.

Expected result

A subframe with a data: or blob: source loads in Web Viewer, in the same way as an https:, about:blank, or srcdoc subframe.

For the Muse example, the Space content should render inside Web Viewer after sign-in, as it does in a regular browser.

Actual result

The data: (and blob:) subframe navigation starts but never completes:

  • The iframe’s load event does not fire.
  • The frame’s document remains about:blank, even though its src is a data:text/html;charset=utf-8,... URL.
  • No did-frame-finish-load or navigation commit is observed for the data: frame.

For Muse Spaces, the console shows:

[CvmSpaceBundle] CVM frame did not complete its document-bound handshake

Error: CVM frame readiness timed out
readinessStep: 'authored_document'

The outer CVM iframe itself loads successfully (HTTP 200, DOM element created), but its inner iframe — which loads the Space content from a data: URL — never becomes ready, so the handshake times out and nothing is displayed.

Environment

Reported on:

  • Operating system: Windows 11
  • Obsidian: 1.15.0
  • Electron: 43.8.3
  • Chromium: 150.0.7871.250
  • Feature: Core Web Viewer plugin
  • Site in the real-world example: https://muse.ai (Muse Spaces)
SYSTEM INFO:
	Obsidian version: 1.15.0
	Installer version: 1.14.5
	Operating system: Windows 11 Home 10.0.26200
	Login status: not logged in
	Language: ja
	Insider build toggle: off
	Live preview: on
	Base theme: dark
	Community theme: Minimal 7.4.7
	Snippets enabled: 3
	Restricted mode: off
	Plugins installed: 26
	Plugins enabled: 17
		1: Minimal Theme Settings v7.3.1
		2: Style Settings v1.0.7
		3: m4v-to-mp4-fix v1.0.0
		4: Kanban-fix v2.0.51
		5: Media Library v0.1.0
		6: Own Surfing v1.0.0
		7: Web Viewer UA Override v1.2.0
		8: YTranscript v1.5.0
		9: Workspaces Plus v0.8.0
		10: Web Viewer Auto Download v0.1.0
		11: Video Rating v0.1.0
		12: Tab Groups v0.1.0
		13: Code Space v2.6.3
		14: Custom New Page v0.1.0
		15: Webview Mouse Nav v0.1.0
		16: Devtools v1.0.0
		17: Webviewer Image Downloads v0.1.0

RECOMMENDATIONS:
	Custom theme and snippets: for cosmetic issues, please first try updating your theme and disabling your snippets. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community theme and snippets.
	Community plugins: for bugs, please first try updating all your plugins to latest. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community plugins.

Also reproduced on Obsidian 1.15.0 with the same Chromium generation, using the minimal example.com test above, so this does not appear to be fixed in the current version.

Additional information

How Muse Spaces uses a data: iframe

Spaces uses nested iframes. The inner iframe that carries the actual Space content is created with a data: source:

Muse
 └─ CVM iframe
     /api/hatch/cvm-frame?protocol=3&...
      └─ INNER iframe
          data:text/html;charset=utf-8,...
          └─ Space content

Creating the iframe element and fetching the CVM frame both succeed. Only the inner data: document never commits.

What has been ruled out

  • Content Security Policy: The CVM response explicitly allows this framing. Its CSP includes frame-src data: blob: ..., so a plain CSP refusal does not explain the failure.
  • Ad blocking: Disabling Web Viewer’s ad blocking does not change the result, and the minimal reproduction on example.com fails in the same way.

Replacing the inner iframe’s data: URL with an equivalent blob: URL also did not help, which matches the minimal test: blob: subframes fail in the same way as data: subframes.

Likely cause

Inspection of Obsidian’s main process (obsidian.asar, main.js) shows a navigation guard registered for Web Viewer guests on did-attach-webview:

  • Main-frame navigation (will-navigate) is cancelled for non-HTTP(S) URLs.
  • Subframe navigation (will-frame-navigate) is cancelled unconditionally whenever the URL is not HTTP(S).

A data: or blob: inner iframe therefore hits this guard directly: the navigation is cancelled before the document can commit, while https:, about:blank, and srcdoc subframes are unaffected. This matches all of the observations above, including why switching from data: to blob: makes no difference.

Suggested fix

Please consider allowing at least data: and blob: URLs for subframe navigation in Web Viewer, while keeping the restriction in place for main-frame navigation and for other schemes.

This pattern — loading an app document into a sandboxed inner iframe from a data: URL — is used by real web apps, so the current guard breaks them silently: the page itself loads, with no visible error in Web Viewer, and only the embedded app content is missing.

Thank you for looking into this.