脆弱性対応のため yarn.lock の更新を行う

ある日 GitHub から怒りのメッセージが届きました

55件のセキュリティアラートがあります

前日まではなにもなかったので驚いたのですが、別に大きなセキュリティホールが発見されたわけではなく、過去の分も含めて通知されていなかった脆弱性が急に届くようになったようです。ライブラリのアップデートを怠っていたのが悪いのですが、このまま放置というわけにも行かないな、ということで一気にがっつりアップデートを行うこととにしました

スケジュールを決めて告知を行う

Carely は 40人近い体制で開発しているため、ライブラリのアップデートを一気に行うと既存の開発とコンフリクトが発生してしまい危険です。腹を決めて、一気にアップデートをするぞ!ということで某日の定期リリース直後に対応開始、その週の中盤でリリース作業するぞということでスケジュールを決めました

ライブラリのアップデートとはいえ api クライアントのアップデートも含まれていたので、最低限必要なリグレッションテストの項目を作成して QA チームにも共有しつつ、開発の週次定例でアップデートを行うことを告知します

作業開始

当日は朝からスタンバってリリース用の PR が作成された直後に作業ブランチを作って作業開始します。管理用の google sheets を作成し、ライブラリとそれぞれに対してどういう対応をしたのかを記載しながら対応していきます(この時、どこでどう使われているかをシートに記載しておくと動作確認がスムーズになります)

yarn.lock の依存関係を確認する

まずは対象となるライブラリの依存関係を確認します

${ライブラリ名}@${指定バージョン}:
  version "${実際にインストールされたバージョン}"
  resolved "${実パッケージの URL}"
  integrity sha512-${ハッシュ}
  dependencies:
    ${依存ライブラリ名} "${依存バージョン}"
    ${依存ライブラリ名} "${依存バージョン}"
    ...

どこの dependancies にも存在していないパッケージは package.json 経由でインストールされており依存関係がないので気にせずにバージョンをあげることができます

ひとつのライブラリから依存されている場合は、依存元のライブラリのバージョンをあげることで問題ないバージョンに上がる場合が多いです。複数の場合は、それぞれでどのバージョンに依存しているかを確認します

また、この時ライブラリのインストール時期によって同じ依存ライブラリでもバージョンが異なっている場合があるのでこのタイミングで揃えてしまいましょう

ライブラリのバージョンをあげる

対象のライブラリのバージョンもしくは依存元のライブラリのバージョンのバージョンのどれをどこまであげるかが決まったら、バージョン間の差分を確認してバージョンを上げても大丈夫かどうかを確認していきます。すべて見切ることはできませんが、最低限どんな変更がなされたのかを把握できる程度には見ておきましょう

また、この時どのバージョンまであげるかの確認も必要です。パッチやマイナーバージョンの更新で問題ない場合はあまり気にしなくても大丈夫ですが、メジャーバージョンが上がる場合には動かなくなる可能性があるので、脆弱性が解決できていて動作するギリギリのバージョンを見極めないといけません。その場合は対象ライブラリの各バージョンの package.json を参照するとどのバージョンがなにに依存しているかを確認できます

対象のバージョンが決まったら、 yarn upgrade package@version でアップグレードします。修正後に依存関係が想定通りになっているか yarn.lock を目視で確認しましょう

上げられないライブラリの対応を考える

依存関係の問題でどうしてもあげることのできないライブラリというのは存在します。それらは個別に「そもそもそのライブラリ以外の選択肢を探す」「 devDependancies なので許容する」など対応方針を考えます

Carely ではビルド関係のものが多かったことと、 webfont の生成などで古いバージョンが使われていたため、これらは後々の課題として許容することにしました

仕上げを行う

ここまでの対応をライブラリごとにやっていくわけですが、半分くらいですでに6時間が経過していて永遠に終わらなそうな気持ちになってしまいます。ですが、前半のライブラリのバージョンアップで後半の分も一緒に改善しているパターンもありなんとか 8時間オーバーくらいですべてのライブラリの更新が完了しました

重複したライブラリを綺麗にする

ここまでである程度綺麗になりましたが、まだまだ deduped なライブラリが存在しているため ``yarn dedupe` を実行して可能な範囲でライブラリのバージョンを最新にします

脆弱性が改善したか確認する

実際に GitHub でデフォルトブランチにマージするまでセキュリティアラートに変更はあります。ローカルで脆弱性がどうなったか yarn audit を実行して確認しましょう

# 修正前
317 vulnerabilities found - Packages audited: 4613
Severity: 14 Low | 168 Moderate | 130 High | 5 Critical

# 修正後
152 vulnerabilities found - Packages audited: 3428
Severity: 5 Low | 81 Moderate | 65 High | 1 Critical

Critical が残っていますが、これは webpack が依存しているものなのでプロダクションで実行されるコードではありません。脆弱性が減っただけではなく、パッケージの総数も大きく減って node_modules のサイズも改善できました。なんで今までやってなかったんだ

リリースをする

QA環境で動作確認をしつつリリースを見計います。さすがに完全に安全だという保証はできなかったのでマネージャー陣とも連携し、最悪ロールバックができる体制でリリースを行いました。結果的には問題なくリリースできたので杞憂でしたがドキドキですよね

そのあとは、次回のリリースに影響がないようにアップデートされて旨を告知して、最新版の取り込みを促して作業終了です。ひさびさに体力を削った年の瀬の業務でした


この記事は iCARE の技術顧問がどんな事をやっているか - 2021アドベントカレンダー の24日目の記事です


この記事が気に入ったらサポートをしてみませんか?