Reject absolute paths in devToolsFileFromPath#9844
Conversation
There was a problem hiding this comment.
Code Review
This pull request improves path validation in devToolsFileFromPath to prevent arbitrary file reads by rejecting absolute paths and ensuring the resolved path is within the DevTools directory. The reviewer recommends adding automated tests to verify these security-critical checks and prevent regressions.
| if (pathFromDevToolsDir.contains('..') || | ||
| path.isAbsolute(pathFromDevToolsDir)) { |
There was a problem hiding this comment.
[MUST-FIX] Please add automated tests to verify these security-critical path validation checks.\n\nSince this change fixes a security vulnerability (arbitrary file read via path traversal/absolute paths), it is crucial to have automated tests to prevent regressions.\n\nThe tests should cover:\n- Valid relative paths (should be allowed and return the file if it exists).\n- Absolute paths (should be rejected).\n- Path traversal attempts using .. (should be rejected).\n- Root-relative paths (e.g., starting with / or \\ on Windows, which might bypass path.isAbsolute but should be caught by path.isWithin).
References
- All changes should include automated tests to ensure correctness and prevent regressions. (link)
Problem
LocalFileSystem.devToolsFileFromPath()is documented as "Only files within~/.flutter-devtools/can be accessed" and enforces that withpathFromDevToolsDir.contains('..'). However it does not reject absolute paths.path.join(devToolsDir(), pathFromDevToolsDir)discards the base directory when the second argument is absolute, so an absolutepathFromDevToolsDir(which contains no..) escapes the intended directory.This is reachable via
getBaseAppSizeFile/getTestAppSizeFile(handlers/_app_size.dart,appSizeBase/appSizeTestparameters) ->devToolsFileAsJson->devToolsFileFromPath, allowing a caller to read an arbitrary.jsonfile on the machine rather than only files under~/.flutter-devtools/.Fix
path.isAbsolute) in addition to the existing..check.path.isWithin(devToolsDir, resolvedPath)containment check on the resolved path.