-
Notifications
You must be signed in to change notification settings - Fork 122
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
Permission - Environment variables #993
Comments
Hi @daeyeon! As I posted in the PR:
I feel we should stick all the future scopes to real threats, mostly from third-party packages. For instance, restricting access to I was planning to bring up that discussion when we finish the current initiatives, but I'll mention it beforehand and keep an asynchronous discussion in the Permission Model roadmap issue. |
@RafaelGSS Thanks for clarifying the scope. I feel I got a better understanding of the direction we should take from the security perspective. If there would be something I can contribute that aligns with the scope, I'd be happy to participate again. |
So @daeyeon, we've discussed it a bit in the Security WG session and Michael seems to agree with the Environment Permission addition. As a TL;DR my concern was replied:
From @mhdawson: It seems to fall under the same rule as the file system. If you install a malicious package by mistake, it's essential to reduce the attack vector as much as you can. Therefore, selecting either if the binary has access to process.env or which environment variables would be available seems something useful. -- Feel free to edit this quote if I don't understand correctly. Basically, by reading the pull request again, the concerns raised there were:
Quoting @tniessen:
Unless the environment permission works as a boolean (enabled/disabled), I don't see why specifying a list of allowed environment variables would prevent an attack vector. For instance, So, @mhdawson or anyone else from @nodejs/security-wg who wants to step in a share your point of view would be much appreciated. For now, I can agree only with denying access to the entire environment permission pinging folks from the PR: @tniessen @ljharb @Qard @richardlau in case you have other thoughts/objections on this. |
My thought is that environment variables are used to provide sensitive tokens, etc. to a running applicaiton through the environment. For example if an appliation read/printed all environment variables that might be concern even if it's not malicious code doing it. The ability to prevent access to the environment would help minimize errors that could expose sensitive information shared through the environment. I think the model of deny all and then possibly whitelist a small subset would best fit that scenario. |
FWIW I know of one requested use case regarding environment variables, nodejs/diagnostics#332 / nodejs/node-report#114 (this was the report feature before it was merged into the core repository). The permissions model proposal for environment variables only dealt with I think the big difference between, say, file permissions and environment variables is that there is a simple way of denying environment variables to Node.js processes -- unset them before running the process. That would side step all sorts of potential side channels in Node.js. I also wonder if there will be a disconnect between limiting to |
What would it prevent? For instance, if I need to have a whitelist for AWS_CREDENTIALS to use in my application, how the pm will prevent other modules to access it? For now, I'm tempted to consider any thoughts @nodejs/security ? |
It's also worth thinking about if identifying presence of an env var can be attacked. For example, if you try to read a blocked env var and it throws that could be interpreted as confirmation that env var exists. Being able to read it is not necessarily required to get enough context about the environment the app is running in to determine other possible steps to take in an attack. Should env just leave any blocked keys undefined as it does with any non-present value? Or perhaps it should also throw on non-present values? There's also the object cloning situation to consider--it's relatively common to blindly clone process.env without caring what's in it for things like passing env minus some changed value into a child process. If accessing a property throws then a lot of apps could suddenly start breaking. |
You're 100% correct that a "blocked" env var should simply be absent, not throw, for the reasons stated. |
In terms of whether or not to throw, I don't see a problem with that. I'd find this feature far less useful if it doesn't throw though. The security concerns aren't really that valid given that if someone is able to monitor the status of the runtime execution then they've likely compromised your system at a higher domain (meaning you have other problems). |
I think every time trying to read whatever env variable not whitelisted should throw, thus making impossible to know which one exist and which not |
As of now, the flag should be behind the |
@darcyclarke When |
@marco-ippolito but then you can distinguish between "locked down" or "the env var simply isn't there", and exposing information to attackers isn't ideal. |
This kind of decision is why we had multiple reaction types in policies. CLI based config will be non-ideal for these complex configurations |
If we're going that route with enabling a small subset we definitely need to support glob patterns which will complexify the whole implementation. eg:
Agree and disagree, it would be seamless for all the current tooling that relies on environment variables to check config for example; however that's also a thing we might want to enforce like This case would be another story, like |
What is the behavior expectation here for things that do populate the |
First I'd like to understand the usability of this feature, then we could nail the tail to the implementation details, such as reading config from a file, throwing exceptions, and so on. For now, nobody has shown this feature will be useful (from a security perspective), considering you will be able to achieve the same from a module that runs in the app startup (for instance, the dotenv can accept a list of allowed env var and throw/undefine the others). |
This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made. |
This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made. |
Hello folks,
I recently made a PR related to environment variables permissions. I basically like the idea of explicitly knowing what resources an application is accessing when it runs.
There were some discussions about whether this permission itself is even necessary. And I started to have my own doubts. Since the environment variables is on the Security WG's permission model roadmap, I'd like to move the discussion here to continue with everyone's thoughts.
1. Needed?
This is for providing transparency about which environment variables are being accessed. It informs users by throwing an error when attempts to access disallowed variables occur. Additionally, it allows for setting up an allowlist in a consistent manner, regardless of platforms.
2. How to do?
The current proposal is to add variable names into an allowlist using the
--allow-env
flag as shown below. Any variables not included in the allowlist will be inaccessible throughprocess.env
.3. How do the others do?
A comparable example is deno, which has the same as this proposed one.
Below are a summarized thoughts of the opposing perspectives discussed so far. Please let me know if there are any omissions or inaccuracies.
1. Needed?
Accessing to environment variables is not inherently dangerous. There is also a question as to why this should be prevented and informed. Regarding the allowlist, there is already a universal way to selectively pass environment variables to any program, which is much easier and better than the new flag provided.
2. How to do?
Since environment variables are just a list of names passed to a process, users can control it in the shell as shown below.
Alternatively, we can rely on package manager to only selectively pass environment variables to child processes.
(daeyeon: I guess we could use
cross-env
to do this.)3. How do the others do?
There is a concern about the code complexity. Deno is designed to have a built-in and useful permission system from the beginning, which is not the case with Node.js. Since the easy way to control it externally exists, we need to consider the worth of the complexity. Plus, catching up with questionable features shouldn't be our goal.
The text was updated successfully, but these errors were encountered: