Skip to content

feat(File Explorer): Add configurable local image rendering to Markdown previewer#47857

Open
st-gr wants to merge 1 commit into
microsoft:mainfrom
st-gr:feature/markdown-local-images
Open

feat(File Explorer): Add configurable local image rendering to Markdown previewer#47857
st-gr wants to merge 1 commit into
microsoft:mainfrom
st-gr:feature/markdown-local-images

Conversation

@st-gr
Copy link
Copy Markdown

@st-gr st-gr commented May 13, 2026

Summary

  • Adds a "Show local images" toggle in PowerToys Settings (File Explorer > Markdown)
  • When enabled, renders images referenced via relative paths or local file paths in the Markdown preview pane
  • Uses WebView2 SetVirtualHostNameToFolderMapping to securely serve local image files
  • Default: OFF (preserves existing behavior)

Fixes #40787
Fixes #3713

Security model

Scenario Behavior
Setting OFF (default) Existing behavior — all images blocked, info bar shown
Setting ON + relative path (media/img.png) Resolved against .md directory, rendered if under that tree
Setting ON + path traversal (../../secret.png) Blocked — Path.GetFullPath + StartsWith check fails
Setting ON + remote URL (https://evil.com/track.png) Always blocked
Setting ON + data:/javascript: URI Always blocked
Script execution Always disabled (IsScriptEnabled = false)

Implementation

Two layers were blocking images:

  1. Markdig AST layer (HTMLParsingExtension.cs): replaced image URLs with #
  2. WebView2 layer (MarkdownPreviewHandlerControl.cs): returned HTTP 403 for all non-HTML requests

Changes:

  • HTMLParsingExtension: conditionally resolves markdown ![](path) images to virtual host URLs with path traversal protection
  • MarkdownHelper: regex-rewrites relative src="" in raw HTML <img> tags to virtual host URLs
  • MarkdownPreviewHandlerControl: maps markdown directory via SetVirtualHostNameToFolderMapping("localmdimages", dir, Allow) and allows those requests through the resource filter
  • Settings UI: new toggle nested under the Markdown preview expander
  • Handler Settings.cs: reads EnableMdLocalImages via SettingsUtils

Test plan

  • Toggle OFF: images blocked, "pictures blocked" info bar shows (existing behavior)
  • Toggle ON with relative paths: ![](media/image.png) and <img src="media/image.png"> render
  • Toggle ON with path traversal: ![](../../etc/passwd) → blocked
  • Toggle ON with remote URL: ![](https://evil.com/track.png) → blocked
  • Toggle ON with data: URI: blocked
  • Other preview handlers (Monaco, SVG, PDF) unaffected
  • Settings toggle appears under File Explorer > Markdown section

🤖 Generated with Claude Code

Comment thread src/common/FilePreviewCommon/HTMLParsingExtension.cs Fixed
Comment thread src/common/FilePreviewCommon/MarkdownHelper.cs Fixed
@github-actions

This comment has been minimized.

Add a "Show local images" toggle in PowerToys Settings (File Explorer >
Markdown) that allows the preview handler to render images referenced
via relative paths from the markdown file's directory.

Implementation:
- HTMLParsingExtension: conditionally resolve local markdown images
  via virtual host URL with path traversal protection
- MarkdownHelper: regex-rewrite relative src attributes in HTML img tags
- WebView2: use SetVirtualHostNameToFolderMapping to serve local images
  via https://localmdimages/ virtual host
- Settings UI: toggle in PowerPreviewPage.xaml with ViewModel binding
- Handler Settings: read EnableMdLocalImages via SettingsUtils

Security:
- Default: OFF (existing behavior preserved)
- Only images under the markdown file's directory tree are allowed
- Remote URLs (http/https/data/javascript) always blocked
- Path traversal blocked via Path.GetFullPath + StartsWith check
- WebView2 scripts remain disabled (IsScriptEnabled = false)

Fixes: microsoft#40787
Fixes: microsoft#3713

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@st-gr st-gr force-pushed the feature/markdown-local-images branch from 58b36a5 to f493c74 Compare May 13, 2026 12:19
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.

Show local images in Markdown files Markdown Preview doesn't allow user to unblock images from being shown

2 participants