Skip to content

Validate extension file system access - #10083

Open
johnpryan wants to merge 2 commits into
flutter:masterfrom
johnpryan:validate-extension-filesystem-access
Open

johnpryan wants to merge 2 commits into
flutter:masterfrom
johnpryan:validate-extension-filesystem-access

Conversation

@johnpryan

Copy link
Copy Markdown
Contributor

Ensure that extensions that are found in ExtensionsManager._addExtensionsForRoot() return DevToolsExtensionConfig objects with valid extensionAssetsPath URIs.

  • On Windows, Dart's Uri.toFilePath() translates a non-empty host (e.g., file://attacker.example/share/proj) into a Universal Naming Convention (UNC) path (\\attacker.example\share\proj), causing the OS to initiate a network connection. This is checked in the assertUriFormat helper function.
  • Disallow relative paths in config['buildLocation'] In ExtensionsManager._addExtensionsForRoot. This prevents path.join() from wiping out preceding path components and pointing extensionAssetsPath at a parent directory.
  • Prevent extensions from using symlinks to gain arbitrary filesystem access. path.isWithin() doesn't inspect the disk, so we check that pageRoot and location are resolved using Directory.resolveSymbolicLink before calling path.isWithin.

This makes progress towards:

…sionsForRoot()` return `DevToolsExtensionConfig` objects with valid `extensionAssetsPath` URIs.

* On Windows, Dart's Uri.toFilePath() translates a non-empty host (e.g., `file://attacker.example/share/proj`) into a Universal Naming Convention (UNC) path (`\\attacker.example\share\proj`), causing the OS to initiate a network connection. This is checked in the  `assertUriFormat` helper function.
* Disallow relative paths in `config['buildLocation']` In `ExtensionsManager._addExtensionsForRoot`. This prevents `path.join()` from wiping out preceding path components and pointing `extensionAssetsPath` at a parent directory.
* Prevent extensions from using symlinks to gain arbitrary filesystem access. `path.isWithin()` doesn't inspect the disk, so we check that `pageRoot` and `location` are resolved using `Directory.resolveSymbolicLink` before calling `path.isWithin`.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances security and path validation in ExtensionsManager by rejecting file:// URIs with non-empty hosts (UNC paths), absolute, missing, or non-directory buildLocation paths, and symbolic links resolving outside the extension build or package root. It also adds validation for the package root URI in the server API handler and includes comprehensive unit tests. The feedback suggests optimizing the symlink validation loop in _validateAndResolveExtensionLocation to only inspect entries that are actually symbolic links, thereby avoiding redundant synchronous I/O operations on regular files and directories, and allowing the removal of the _resolveTargetPath helper.

@johnpryan
johnpryan requested a review from srawlins November 10, 2026 01:23

@srawlins srawlins left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phew! Go tests go!

This branch has not been deployed

No deployments
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