-
-
Notifications
You must be signed in to change notification settings - Fork 27
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
esbuild leaves the sandbox #58
Comments
@gregmagolan do you guys have a plan for how to deal with this? I remember you mentioning Having some pretty major issues with the esbuild rules as-is, due to the sandbox escape. One is that, on developer machines, if an NPM package is missing from the inputs, it will probably be resolved from the PNPM-created node_modules folder in the workspace created by the developer running |
It's a hard one to fix. We'll probably have to make changes to esbuild itself to expose the hooks needed to prevent it from following symlinks out of the sandbox. |
I wonder if we should file a bug on esbuild asking for what we want. Unlikely, but never hurts to ask? |
I wonder if this is the same issue causing building esbuild(
name = "lib",
entry_point = "program.mjs",
deps = [
#"//location:location_ts_proto", # a real dependency of program.mjs that we leave out, and yet still esbuild succeeds.
"//:node_modules/google-protobuf",
],
) |
Turning on preserve_symlinks does seem to resolve the issue for me. It is unclear to me precisely why preserving symlinks cannot be enabled. It seems like every tool like esbuild will need to be patched if preserve_symlinks is set to false when the tool is invoked. In any case, I tried to modify the launcher.js with an onResolved plugin based on #32. I don't think the plugin hook has enough information to fix the problem. The resolved import path and set of files used to perform the resolution is not passed to the plugin, so it seems the plugin would have to implement its own import resolution (traversing node_modules, reasoning about file extensions, etc.). esbuild seems to use its own file system library as sort of a virtual file system. It seems that could be modified to hide non-sandbox files from esbuild's resolver. https://pkg.go.dev/github.com/evanw/[email protected]/internal/fs Maybe a simple hook like It seems the desired behavior (when preserveSymlinks=off) is to have a file system that consists of
... naively, I would expect bazel to provide this functionality as part of the sandbox it sets up. However, it seems the sandbox environment allows reading files from any path on disk. FYI, here some debug output from the onResolve plugin. You can see how the final resolved path isn't passed to the plugin.
|
On second thought to the above comment, it seems the "onLoad" plugin callback might have enough information to catch sandbox escapes. https://esbuild.github.io/plugins/#on-load-arguments |
I think adding a capability to esbuild makes sense, if the maintainers accept it. That's how we get other tools to behave how we expect under Bazel. I imagine another answer is just a more hermetic sandbox. You could try the docker strategy for all esbuild actions for example, or remote if you have access to a RBE cluster. Maybe we should try that and add to the docs. |
This implementation uses an OnLoad plugin to catch when a file is loaded that is not in an allowlist of files. The allowlist is all the files within the BAZEL_BINDIR and all of the symlink targets of those files. This may not prevent all sandbox escaping modes. The esbuild Go code may still access unsandboxed files in the course of loading files that are in the sanbox. Addresses aspect-build#58.
This implementation uses an OnLoad plugin to catch when a file is loaded that is not in an allowlist of files. The allowlist is all the files within the BAZEL_BINDIR and all of the symlink targets of those files. This may not prevent all sandbox escaping modes. The esbuild Go code may still access unsandboxed files in the course of loading files that are in the sanbox. Addresses aspect-build#58 and requires aspect-build/rules_js#793 to work properly.
This implementation uses an OnLoad plugin to catch when a file is loaded that is not in an allowlist of files. The allowlist is all the files within the BAZEL_BINDIR and all of the symlink targets of those files. This may not prevent all sandbox escaping modes. The esbuild Go code may still access unsandboxed files in the course of loading files that are in the sanbox. Addresses aspect-build#58 and requires aspect-build/rules_js#793 to work properly.
This implementation uses an OnLoad plugin to catch when a file is loaded that is not in an allowlist of files. The allowlist is all the files within the BAZEL_BINDIR and all of the symlink targets of those files. This may not prevent all sandbox escaping modes. The esbuild Go code may still access unsandboxed files in the course of loading files that are in the sanbox. Addresses aspect-build#58 and requires aspect-build/rules_js#793 to work properly.
I think #112 fixes this to some extent. I'm guessing there are some edge cases that it doesn't handle, like if esbuild loads a |
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
By default esbuild uses any local tsconfig.json file. With sandboxing issues (#58) this may unexpectedly cause `esbuild_bundle` to pickup any local tsconfig.json. A custom tsconfig can now be set using `esbuild_bundle(tsconfig)`. By default an empty tsconfig is used to prevent unexpected sandboxing issues.
Just an addition here, I was able to make a plugin with |
Do you have any examples of code you could share publicly? This would be great to have! |
THere's a flag |
Fix for this (from #160) is included in the v0.17.0 release |
Since we turn preserveSymlinks off so that node_modules resolution works with the rules_js symlinks node_modules tree, esbuild will currently leave the sandbox by following symlinks. The rules_js node fs patches don't apply to the golang binary. There is currently no hook in esbuild where we can customize module resolution so that esbuild stays in the bazel sandbox.
If bundling .js files that come from transpiled sources, it is currently recommended to set the following configuration
so that esbuild doesn't pick up and re-transpile the .ts sources it can find outside of the sandbox and seems to prefer (#57 (comment)).
The text was updated successfully, but these errors were encountered: