In my previous post, I explored converting existing TravisCI jobs into GitHub Actions. If you're unfamiliar with GitHub Actions, I recommend reading that post first as it explains some of the basics. Since then, I've spent a bit more time experimenting with them and have found a slightly concerning security issue.
GitHub Actions allows you to use encrypted secrets for things like API keys that you wouldn't want to store in code. You can then pass those secrets into actions for use during deployment.
As you can see from the screenshot, secrets are "environment variables that are encrypted and only available when this action executes." They key phrase here is that they are "available when this action executes." Suppose I add that secret key to that action:
Now consider that actions are all controlled by code. Let's look at our build action from the previous post:
#!/bin/sh -l sh -c "echo 'Build the project'" composer install
If you had GitHub Actions set up to respond to pull requests and simultaneously injected the secret environment into that action, a malicious user could modify your action accordingly:
#!/bin/sh -l sh -c "echo 'Build the project'" composer install # Malicious user adds this: echo $SUPER_SECRET_KEY
Then when that action is executed you get a log that looks something like this:
...NORMAL BUILD MESSAGE UP HERE... phpunit/phpunit suggests installing ext-xdebug (*) phpunit/phpunit suggests installing phpunit/php-invoker (^2.0) Generating autoload files This is super secret. Don't tell anyone. ### COMPLETED Build 23:03:38Z (47.403s)
Our secret was just exposed to the entire world.
What GitHub says about this
For me this is a critical blocker to using this in any sort of production environment. Regardless of whether or not you're in a public or private repo, you don't necessarily want every developer in your repo to be able to intentionally, or even accidentally, expose your secrets. But what does GitHub have to say about it?
GitHub's documentation currently states:
Warning: Do not store production secrets in the API during the limited public beta period. Production workflows should not be used during the limited public beta.
Warning: Be careful that your secrets do not get printed when your action runs. Secrets are not obfuscated from the command output and could be visible in logs.
I definitely agree with both sentiments. When I reached out to GitHub directly they elaborated a little bit:
This is an intentional design decision and is working as expected. If you have the ability to write to the main.workflow then you have the ability to expose the secrets in many ways. We are planning to make the messaging more clear about how permissions works for GitHub Actions and we may make this functionality more strict in the future, but don't have anything to announce now.
Their solution for now is mainly just to fix the messaging. But in my opinion, it seems way too easy for someone to accidentally to misuse these. That said, if they make the warnings more obvious when adding the credentials, that could at least help.
So for now avoid using actual production secrets in GitHub Actions.
See GitHub's Storing Secrets documentation for more information about this.