I'm not sure. When using `::set-output name=spam::eggs`, you seem to have to refer to it via `steps.foo.outputs.spam`. So if you keep steps that set outputs very simple, and/or the set-output echo is the last command of the step, then it should mitigate that?
Is the general consensus that `$GITHUB_ENV` offers less attack surface, despite not being scoped to a step?
Some guidance on this would be great from Github's side. Also appreciated: a way of turning off magic stdout strings in the YAML, and a way to set outputs via a more robust mechanism, and/or to scope which steps can modify which environmental variables. I get not wanting to break existing CI runs, but giving the people who want it an option to harden the CI proactively would be great. I don't really care if this would break some existing actions, either - seems fine to do for opt-in?
I’ve been using $GIT_ENV for setting environment variables, and though I read about the stdout commands I never got to using them.
It’s one of those “but of course” moments realising that any cli tool can trigger commands with it’s stdout.
As you mentioned setting outputs is rather crucial, I guess using stdout is the only way todo that.
There are definitely a lot of security things to consider when using actions. I read the code of any community actions I use but, especially after reading this alert, I feel like there are a lot of places where malicious code could cause damage.
It seems like most people here don't see what the root cause here is.
System and user level processes with high order 'actions' for idempotent handling of secure channel operations (session negotiation, out-of-band data) are vulnerable to xss, side-channel attack for 'actions' that use stdout on/at execution of low order operations handling packed binary data that upon execution may contain shell code or encoded instructions.
they will patch a PoC, but how will we know the root cause is patched? the service parameters can be fuzzed by someone to check for injection (if they can).
I think we’re getting pretty close to understanding the root cause.
Tools that you run in actions can trigger the stdout commands (setting env variables and a few others) via printing to the console.
To do some damage though they need a few other things to happen. The example given is a node process that is run after the attacker has set an env variable with arbitrary code, which node reads and executes.
Additionally since some actions print the contents of PRs and Issues to the console, these can effectively do the same thing. So the attacker doesn’t need to control a cli tool stdout output, they just need to
create a PR/Issue with the malicious code. If an automated workflow writes the PR/Issue to stdout, then the malicious code in the PR/Issue is executed.
Since it’s possible for any action to run commands by writing to stdout, you have to trust that all the actions you use don’t print malicious stuff to stdout, and they themselves might not be malicious, but they might print stupid stuff that contains untrusted input like the contents of PRs/Issues.
It’s not made any easier by the fact that the workflows are in the repo for the attacker to read and study, so they can see exactly what will happen before their attack.
This whole method of triggering commands via stdout is very dodgy, and there is no way to either turn it off, or narrow the scope of what is executed, and it’s not easy to see what happened after the fact either.
At the minute you just have to be very diligent at checking that your actions aren’t printing stupid stuff to stdout that could cause execution of malicious code later in your workflow.
If it’s only the setting of env variables that causes issues, then they might be able to just turn that off because there is another safer mechanism (writing to $GITHUB_ENV) to set env variables.
There might very well be other attack surfaces though that I haven’t thought of.
Is the general consensus that `$GITHUB_ENV` offers less attack surface, despite not being scoped to a step?
Some guidance on this would be great from Github's side. Also appreciated: a way of turning off magic stdout strings in the YAML, and a way to set outputs via a more robust mechanism, and/or to scope which steps can modify which environmental variables. I get not wanting to break existing CI runs, but giving the people who want it an option to harden the CI proactively would be great. I don't really care if this would break some existing actions, either - seems fine to do for opt-in?