確認したいこと
確認したいことは、「CircleCIの歯車アイコン(⚙)で設定した環境変数がどういうときにリークする可能性があるか」です。
サービスのトークンなどを環境変数として設定する用途などで利用すると思いますが、トークンの流出が怖いのでどういうときに起こりうるかしっかりと確認したいと思います。
検証方法
- CircleCI 2.0を使います。
- コンテナベースのビルドで試しました。
-
docker: [image: ...]
を使っていてmachine: true
は使ってません。 -
circleci/node:10
イメージを使いました。
-
-
MY_SECRET1
にThis is secret message!
を設定しました。 - 環境変数の取得方法は以下の3つを試しました。
echo $MY_SECRET1
-
env
コマンド node -e 'console.log(process.env)'
console.log(process.env)を使った理由
console.log(process.env)
を使うと環境変数名と値がkey-valueのオブジェクトとして出力できます。
{ CIRCLE_NODE_INDEX: '0',
YARN_VERSION: '1.13.0',
CIRCLE_COMPARE_URL: '',
...省略...
}
console.log(process.env)
みたいに言語の機能を使ったのは、以下のような可能性を排除したかったからです。
-
$MYSECRET1
が含まれていたら、コマンド動かさないとか、 -
env
コマンドに細工しているとか、 - 出力に秘密の環境変数の値が含まれていたら消すみたいなフィルタリング
process.env
のオブジェクトにkey-valueとして含まれていなかったら、おそらくCI動く前から環境変数をセットしないで動かしている内部実装なのかなと判断できると思いました。
Node.jsを使った意味は特にないです。
結果
GitHubアカウントは2つ用意して行いました。
どちらのアカウントで起こったことなのかを分かりやすくするために名前つけます。
- オリジナルリポジトリのアカウントをauthorのAさん、
- フォークしてコントリビュートする人をcontributorのCさん とします。
CさんがforkしたリポジトリをCさんのCircleCIでビルドした場合
以下のような結果で、forkした場合にビルドされてもリークはしなくて安心です。(確かこれは公式ドキュメントに書いてあった気がします)
- echo $MY_SECRET1`: 何も表示されない
-
env
コマンド:MY_SECRET1
が含まれていない -
node -e 'console.log(process.env)'
:MY_SECRET1
が含まれていない
(この挙動を見る限り、MY_SECRET1
が完璧にセットされない状態で、CIが動いている感じがします。)
CさんがforkしたリポジトリからAさんにプルリクエストした場合
この場合、CさんがCircleCIのアカウントを持っていれば、passしたところに✔がついたりして、CircleCIが走ります。ただ持っていなければCircleCIが動かないため上記の結果と同じになります。
Cさんのプルリクエストをマージしたとき
authorのAさんが緑色の[Merge]ボタンを押してマージすると、環境変数はすべて方法で、表示されました。
- echo $MY_SECRET1`: 表示される
-
env
コマンド:MY_SECRET1=This is secret message!
が含まれている -
node -e 'console.log(process.env)'
:MY_SECRET1: 'This is secret message!'
が含まれている。
一番簡単なecho $MY_SECRET1
の結果です。値"This is secret message!"が表示されてます。
まとめ
「マージは慎重に!」と思いました。
マージしてauthorのCircleCIでビルドされれば環境変数は取得可能になってしまいます。
また、うっかりデバッグでauthorがenv
を表示したりするのも危険ということが分かります。
たった3文字で大変なことが起こる可能性があります。
感想としては、
env
をリモート端末に送信するような書かれてたりすれば、うっかり漏れたりする可能性がある気がしました。難読されたシェルとJSFuckとか色々読みにくくする方法はたくさんあると思います。
それら使ったりすればパッと見わからないように細工される可能性もあると思いました。
Travis CIだとコントリビューターがプルリクエストすると、authorのアカウントでCIでも動くので、Travis CIのときの環境変数の流出の可能性についてもちゃんと把握しておきたいです(ちょっと今Travis CI障害中なので先にCircle CI調べました)。
(追記:CircleCIでも、Build forked pull requestsオプションありましたね。Pass secrets to builds from forked pull requestsっていうオプションがあるくらいなのでこれがoffの限り、環境変数は渡されなさそうですね。)
蛇足
"This is secret message!"の"a"なかったです...