Closed guybedford closed 3 years ago
I assume the example is supposed to be (trailing slash in specifier key):
{
"imports": {
"mapped/path/": "/path/to/map/"
}
}
Thanks, yes, corrected.
To clarify: are all of the following imports to be rejected in the example above? Or should only the last one be rejected?
import 'mapped/path/../backtrack'
import 'mapped/path/../../backtrack'
import 'mapped/path/../../../backtrack'
(I assumed the former, because 'mapped/path/../backtrack'
can look like 'mapped/backtrack'
which is not mapped by the same "mapped/ath/"
entry)
Yes exactly, all the cases there would be rejected.
In Node.js, we do the full URL resolution, then just have a secondary check that the resolved URL is contained within the resolved target subpath and fail then if it isn't. We do also have added protections there aren't URI-encoded ..
segments for path conversion or node_modules
segments, but those are Node.js specific things.
In the Node.js modules group work on exports, which in many ways shares similiarities with import maps resolution, we've explicitly added some validation to ensure that mappings cannot be back tracked - effectively that
import 'mapped/path/../../../backtrack'
will throw when backtracking below the target mapping's trailing slash base path.For the example case:
the validation step is basically just to check that any resolution using this imports, after applying the full URL resolution also goes through a check that
resolved.startsWith(targetPathWithTrailingSlash)
, and if not to throw a validation error.For Node.js package isolation can be still worked around using absolute URLs, but providing this level of encapsulation makes it more obvious to users that private modules should be private.
Whether that same level of encapsulation encouragement is important to import maps is a question worth considering though, so I thought I would bring it up at least.