-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fs: allow file: URL strings as paths #20944
Conversation
if (!path.startsWith('file://')) | ||
return path; | ||
path = new URL(path); | ||
} else if (path == null || !path[searchParams] || | ||
!path[searchParams][searchParams]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This no longer lines up with the rest of the conditional above this line.
Can we see benchmark results to verify the non-URL cases are unaffected? |
We should try to mitigate the issue described in #10739 (comment) sufficiently (how?), and if we decide to land this, call this out very very explicitly as a breaking change with security implications in our changelog. /cc @nodejs/security |
Good point, I'm not so sure this is a good idea... |
Ummm... is this really a good idea? |
@addaleax one of the things I was actually hoping this could pave the way for as well would be From a security perspective, Such sanitization would likely be designed to whitelist check a path prefix like |
Here's another security case: function readUserFile (name) {
if (name.match(/\/\\/))
throw new Error('Must be a valid name');
// name is taken to be relative to cwd here
fs.readFile(name);
} But because we require the |
I wouldn’t call myself an expert, but I’d expect that something like I’m not saying it’s likely, but my impression is that it’s absolutely something which we need to warn users about in some way. |
Extremely fair question. Scoping on On the sanitization point... with a Also, keep in mind that |
That still leaves If the sanitizer allows slashes but not dot segments, then yes that could be an issue though. But since drive names in windows use So if the sanitizer did |
fwiw, @guybedford and I chatted about this yesterday for a bit and I definitely pointed out that there are challenges with enabling this. I'm not yet convinced we have a clear enough picture of the potential downsides on this. |
> path.normalize('asdf/asdf/../../../../path')
'../../path'
> _.startsWith('../') || _.startsWith('/')
true i.e. this validator would reject your example (and I believe would be a correct validator for fs methods up until now) but accept |
To flesh out the case with drive letters as well - yes Unless anyone has any more to add here, that does seem like the final nail here unfortunately actually - and we likely will want something like @addaleax would you be open to |
See #17658. Without a solution to #17658 (comment), I am -1 on this PR. |
@addaleax ...
Yep, and that's precisely why validation would have to be applied after parsing the file URL and would be required to look at only the |
@guybedford I’m not saying I don’t like this idea – I really do. I might be more easily on board if we were to do this for |
@addaleax that's a very interesting suggestion! |
Yeah, but the point @TimothyGu brought up again remains valid – we’re taking valid file names and doing something else with them if they have a specific format, it’s kind of awkward and a bit scary. (Like, it seems like the kind of thing that could come back and bite us in 5 years like the The best solution might be adding new methods that do this, tbh. |
@TimothyGu I addressed this point in the description of the PR - by checking |
This extends support for WhatWG URL objects in fs APIs to also include file: URL strings beginning with
file://
.The URL standard actually suggests using strings over the object where possible in https://url.spec.whatwg.org/#url-apis-elsewhere, so it would be good to be able to enable such a best-practice.
This will also enable use cases like
fs.readFile(import.meta.url)
for modules, where the URL is provided as a string.While it is possible for files or directories to exist with names like 'file:' or 'file:/', by restricting only to the 'file://' we can reliably distinguish file URLs from unique file paths.
Performance is largely unaffected as there is a fast opt-out of this code path through the string prefix check.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes