From 013b6f4b648e497b036625a0314655f5b7027a94 Mon Sep 17 00:00:00 2001 From: Nathan Totten Date: Mon, 16 Mar 2026 13:59:02 -0500 Subject: [PATCH 1/2] Fix untrusted workspace config resolution executing JS config files Prettier's resolveConfigFile/resolveConfig can require()/import() JavaScript config files (.prettierrc.js, prettier.config.js, etc.), allowing arbitrary code execution even when workspace trust restricted module resolution to the bundled Prettier. Add a workspace.isTrusted guard in resolveConfig() to skip config resolution entirely in untrusted workspaces, returning null (Prettier defaults). Reported by Hector Ruiz Ruiz. Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 2 ++ src/ModuleResolverNode.ts | 10 ++++++++++ src/message.ts | 2 ++ 3 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f17c0568c..ecb552aaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable changes to the "prettier-vscode" extension will be documented in thi ## [Unreleased] +- **Security**: Fixed config resolution in untrusted workspaces to prevent JavaScript config files (`.prettierrc.js`, `prettier.config.js`, etc.) from being executed. Previously, even when workspace trust was enforced for module resolution, Prettier's config resolution could still `require()`/`import()` JS config files, allowing arbitrary code execution. Reported by Hector Ruiz Ruiz. + ## [12.3.0] - Watch `.prettierignore` for changes to invalidate cache (#3942) diff --git a/src/ModuleResolverNode.ts b/src/ModuleResolverNode.ts index afba04b7c..eaad1520a 100644 --- a/src/ModuleResolverNode.ts +++ b/src/ModuleResolverNode.ts @@ -15,6 +15,7 @@ import { INVALID_PRETTIER_CONFIG, INVALID_PRETTIER_PATH_MESSAGE, OUTDATED_PRETTIER_VERSION_MESSAGE, + UNTRUSTED_WORKSPACE_SKIPPING_CONFIG, UNTRUSTED_WORKSPACE_USING_BUNDLED_PRETTIER, USING_BUNDLED_PRETTIER, } from "./message.js"; @@ -402,6 +403,15 @@ export class ModuleResolver implements ModuleResolverInterface { fileName: string, vscodeConfig: PrettierVSCodeConfig, ): Promise<"error" | "disabled" | PrettierOptions | null> { + // In untrusted workspaces, skip config resolution entirely. + // Prettier's resolveConfigFile/resolveConfig can execute JS config files + // (.prettierrc.js, prettier.config.js, etc.) which would allow arbitrary + // code execution. + if (!workspace.isTrusted) { + this.loggingService.logDebug(UNTRUSTED_WORKSPACE_SKIPPING_CONFIG); + return null; + } + let configPath: string | undefined; try { configPath = diff --git a/src/message.ts b/src/message.ts index 53e4b8826..ad0b5d92a 100644 --- a/src/message.ts +++ b/src/message.ts @@ -13,3 +13,5 @@ export const EXTENSION_DISABLED = "Extension is disabled. No formatters will be registered. To enable, change the `prettier.enable` to `true` and restart VS Code."; export const UNTRUSTED_WORKSPACE_USING_BUNDLED_PRETTIER = "This workspace is not trusted. Using the bundled version of prettier."; +export const UNTRUSTED_WORKSPACE_SKIPPING_CONFIG = + "Skipping Prettier config resolution in untrusted workspace. Config files are not loaded for security."; From eabbc9578397e44e307c21cc4e14e89de241dd90 Mon Sep 17 00:00:00 2001 From: Nathan Totten Date: Mon, 16 Mar 2026 14:05:28 -0500 Subject: [PATCH 2/2] Honor requireConfig in untrusted workspaces When requireConfig is true and the workspace is untrusted, return "disabled" instead of null so formatting is correctly skipped rather than proceeding with VS Code defaults. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/ModuleResolverNode.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ModuleResolverNode.ts b/src/ModuleResolverNode.ts index eaad1520a..fd832800d 100644 --- a/src/ModuleResolverNode.ts +++ b/src/ModuleResolverNode.ts @@ -409,6 +409,9 @@ export class ModuleResolver implements ModuleResolverInterface { // code execution. if (!workspace.isTrusted) { this.loggingService.logDebug(UNTRUSTED_WORKSPACE_SKIPPING_CONFIG); + if (vscodeConfig.requireConfig) { + return "disabled"; + } return null; }