音声書き起こし
1. オープニング
@potato4d
こんにちは、UITのpotato4dです。ユーザーインターフェースとテクノロジーを愛する開発者のためのポッドキャスト、UIT INSIDE、今回もやっていこうと思います。今回はですね、最近相次ぐサプライチェーン攻撃への対応策として話題になっているmin-release-ageに関する取り組みについて、社内での取り組みと
@potato4d
あとmin-release-age自体の話をですね、ちょっとプライベートnpmの管理者でもある吉澤さんと話していきたいと思っております。吉澤さん、よろしくお願いいたします。
@rChaser53
よろしくお願いします。プロダクト開発CBU、プロダクト開発ユニット、GOEディビジョンの吉澤です。メインの仕事は今SREの方をやっているんですが、もともと旧UITに所属しておりまして、プライベートnpmの開発運用を現在も続けておりまして、
@rChaser53
そのあたりの関連で今回お呼ばれしたというふうな形だと思っております。
@potato4d
よろしくお願いします。ありがとうございます。
2. 社内プライベート npm の min-release-age 対応
@potato4d
では今日はもう早速本題に入っていこうかなと思うんですけど、今ねかなりmin-release-ageというのがかなりホットな話題になっているかなと思っております。やっぱりどうしてもパッケージの攻撃が日々増えてきている中で、悪意のあるパッケージをインストールしないようにというふうなところで、各手元の.npmrcとかでプロジェクトのリポジトリに
@potato4d
書くことも増えてきたかなとは思いますけど、結構最近弊社内のプライベートnpmではレジストリ内にそういった仕組みを構えているっていう話をお伺いしたので、ちょっとこの場で深掘りしようかなと思っているんですけど、今どういう形で機能を提供してる感じになるんですかね。
@rChaser53
そうですね、今ですと私の提供している社内のnpmレジストリですと、もうデフォルトで、パブリッシュから一日経過しないとバージョンのインストールができない。min-release-ageでいうと1相当の機能が
@rChaser53
レジストリとして提供しているという形になりますね。なので、レジストリで指定しているだけで、.npmrcだとか設定ファイルに何も書かなくても、min-release-ageが強制的に働くという形になっております。当然これだけだと社内のパッケージとかの開発は非常にしんどい形になって
@rChaser53
しまうので、社内のパッケージだけ除外だとか、特定のやつだけ除外みたいな形にもなっております。
3. Verdaccio と前段プロキシの構成
@potato4d
開発元が明確な社内のものとかは、円滑な開発を維持しつつ、外部のパッケージに関しては安全を第一に運用するみたいな形になってるんですね。ちなみにこれって以前何度かUIT INSIDEでプライベートnpmの話をお伺いしてる時に、Verdaccioを基盤にしてるみたいな
@potato4d
話があったかなと思うんですけど、これってVerdaccio側の機能としてもともとmin-release-ageみたいなのがあるみたいなことになるんですかね。
@rChaser53
というわけではなく、実はVerdaccioをベースに前段にアプリケーション・リバースプロキシみたいな形でサーバーを置いておりまして、そこでmin-release-age相当の機能を提供するという話になっております。弊社ですとその前段のところで例えば権限の認証管理や
@rChaser53
認証認可などの処理を行っていたりだとか、こういったmin-release-ageなどの処理を追加で行ったりだとかしているといった形になります。
@potato4d
なるほど、じゃあそのVerdaccio自体に機能はなくて、前段で専用のバリデーションロジックみたいなのを実装して弾くようにしているという形なんですね。
@rChaser53
はい、Verdaccioはもうほとんどnpm installとかnpm publishとかベースとなる処理だけ行っていて、っていう形になります。
4. 24時間以内のバージョンを弾く仕組み
@potato4d
なるほどなるほど。ちなみにこの一日判定して弾くみたいなのは、実際にパッケージの方をダウンロードしに行って、そのリリース日、メタ情報みたいなのを読み取って判断してるみたいな感じになるんですかね。
@rChaser53
そうですね。レジストリに直接例えばAPIのエンドポイントでメタデータをJSONとして取得できるAPIがnpmのレジストリというのは基本的に提供されているんですが、そこにtimeというプロパティがございまして、バージョンごとにいつパブリッシュされたのかというのは
@rChaser53
そこの部分で管理するという形になります。パブリッシュされた直後にレジストリがそこの部分に書き込むみたいな形ですね。
@potato4d
例えば社内npmにアクセスされたときに、まず前段のアプリケーションプロキシみたいなところでnpmjs.comのメタ情報みたいなのを取りに行って、そのtimeベースで二十四時間以内の場合は一つ前のバージョンしか入れられない状態になっているみたいな、そういうことなんですね。
@rChaser53
そんな感じで、正確に言うとそこの部分のtimeにあるものを全件検索して、二十四時間以内のものを全部削ってしまうみたいな話になっています。
@potato4d
あーなるほどなるほど。
@rChaser53
というのは、一つ前のバージョンとかになりますと、結構バージョンの判定がめちゃくちゃでして、例えば0.0.1-alphaだとかbetaだとかこれぐらいだと分かりやすいんですけど、nextだとかなんちゃらの名前になっていて、1個前のバージョンって何なんだよみたいな話になってしまうので、まあ多少
@rChaser53
処理に時間がかかってしまうのは覚悟して全件検索みたいな形になってきますね。
@potato4d
そういうのがいいですね。全件検索して二十四時間以内のやつを取り除いたうち、一番最新にパブリッシュされたものを指定するようになっていく感じですね。
@rChaser53
そういう形になっています。
@potato4d
確かになんかあれすね、nextとかついてるとどれが本当かどれが一番新しいか分かんないですもんね。
@rChaser53
そうなんですよね。困ったことに。まあとりあえず今のところサーバーをガンガン増やさなくてもなんとか動いてくれてるので、結構皆さんもご存知だとは思うんですが、npm CLIのタイムアウトとかの期間は長いですし、リトライ処理とかもガンガンかかってくれてるので、それが原因で動かないぞ
@rChaser53
なんとかしてくれみたいな問い合わせは今のところは来ておりません。
@potato4d
なるほどなるほど。じゃまだUX的にも問題ない状態で。
@rChaser53
はい、許容できるかなというところでは。
5. 機能導入の経緯 — 急増するサプライチェーン攻撃
@potato4d
いいですね。ちなみにこの機能自体を作ったのは結構最近になるんですか?
@rChaser53
去年の10月?9月?実際問題でこの機能自体は2021年だか22年ぐらいにはこんな機能を作ったらどうだみたいな話は部署内では上がっていたんですが、ちょっとそこまで過去は頻度が多くなかったので、
@rChaser53
サプライチェーン攻撃の問題は置いといてもいいだろう、そこまでやらなくても大丈夫なんじゃないかとなってお蔵入りになっていたのが、どんどん頻度が上がってきてしまいまして、じゃあ実装しようかっていうふうな形でレジストリ側で実装したというふうな形になります。
@potato4d
確かにもうここ数ヶ月になってから急に増えましたもんね、サプライチェーン攻撃みたいなのが。
@rChaser53
そうですね。ここに関しては本当に最近だと一週間、二週間に一回は、そのあたりの例えば遠隔で操作できてしまうだとか、認証情報が取得されてしまうからちょっと調べてくれみたいな話で呼び出されるみたいな事態が続いておりますね。
@potato4d
なんかその中で、こうシステム側の仕組みで担保するっていうのはすごい筋のいいアプローチな気がするんで、これはなんか利用者観点でもめっちゃ助かりますね。
@rChaser53
そう言っていただけるとありがたいです。
@potato4d
これが実装される前って、結構手動でbanとか消したりとかしてた感じなんですかね。
@rChaser53
そうですね、手動で依頼があったら初めてそこの分のインストールが走らないようにする仕組みを動かしていたみたいな話だったので、まあ間に合うわけがないんですよね。うん、それって。なんで、まあどうにもならんというのでmin-release-age相当の機能をレジストリで提供したというふうに思います。
@potato4d
なるほど、数が少ないうちは対処療法的なやり方でもよかったけど、ちゃんとちょっと数があまりにも増えてるもんで、仕組みの方で対処したっていう感じですね。
@rChaser53
そうですね、それもありますし、そもそも直近のAxiosとかの件で言うと、npm installが走ってしまった時点でもう遠隔操作ができてしまう可能性があるとかいう話で、もう手遅れなんですよね。
@potato4d
たしかに。最近はあれですもんね、勝手に入れて自分で消えるみたいな感じになってるんで、もう入れた瞬間アウトになって、もう何も分からないみたいなのが多いですもんね。
@rChaser53
そうですね。
@rChaser53
極めて邪悪なものが増えてきてしまっているところではありますが、なんでもう人間の手で毎回毎回やっていてはもうどうにもならない、機械的に処理するしかない形にはなってますね。
@potato4d
そんな中でシステム化されてるのはすごい良い気がしますね。ありがとうございます。
6. min-release-age は何日にすべきか
@potato4d
ちょっとここからの話の発展として、社内での取り組みみたいなところを今お伺いできて、我々としてはというか社内のエンジニアとしてはすごい助かっている状態ではあるんですけど、一般的にはプライベートnpmを使うというのは、npmjs.comにアクセスして開発している人のほうがJavaScriptのデベロッパーでいうと多いかなと
@potato4d
思うんですけど、やっぱりみんな共通してる問題として、min-release-ageって結局いつを設定したらいいんだっけみたいなのってあんまり分かってない部分もあるのかなと思います。そこについてですね、せっかく今回一日っていうふうなところで設定して問題なく運用できてるっていう実績があるかなと思うんで、どう決めていったかみたいなプロセスとか
@potato4d
安全と利便性のバランスみたいなところで言うと、社内向けはゼロっていう話があったかなと思うんですけど、どういうふうに一日に決めたかみたいなのがあったらちょっと教えてもらってもいいですか?
@rChaser53
これはですね、pnpmのドキュメントですね。min-release-ageの先駆けって多分pnpmのminimumReleaseAgeだと思うんですけど、あそこのドキュメントで大半のものは一時間以内に問題を解決する、
@rChaser53
こういったハイジャックに起因したサプライチェーン攻撃とかが発見されてなくなるよっていう話があったんで、そうだねじゃあ一日で十分なんじゃないか、一時間って書いてあるねっていうのが最初のmin-release-ageゼロって、まあmin-release-ageは日付単位でしか設定ができないんで、
@rChaser53
じゃあまあ一時間よりも多い方で最小となると一しかないから一日なんじゃないかなっていう風に設定したというふうなところはありますね。
@potato4d
なるほど。なんかpnpmだとあれですよね、確か秒単位で設定できましたよね。あれは。
7. 「1時間で解決」は本当か — Axios の実例
@rChaser53
そうですね、pnpmの方が色々と具合がいいところは正直な話多いんですよね。そういった点で考えると、とはいえ、この文章も正直な話どこまで信憑性があるのかというところを最近感じておりまして、先ほど話に上がったAxiosの
@potato4d
ほうほう。
@rChaser53
1.14.1などの問題の話ですね。あれは結局公式のnpmレジストリが配信を停止する前に、三時間から四時間ほどかかってるんですよ。
@potato4d
あーそうなんすね。
@rChaser53
その直近の調査とかも、公式のドキュメントで書かれている内容では一時間以内に終わったみたいな感じのことが書いてあるんですけど、うちのセキュリティのメンバーとかが調べたところだと、一日とは言わんけれども数時間くらいは配信が停止される前に公式のnpmレジストリが
@rChaser53
配信が停止されるまでにかかってるみたいな話があって、まあこれ全然一時間じゃないよね。いや過去はそうだったんだけどさみたいな、正直な話になっておりまして。なんで少なくとも、そもそもnpmだと日単位でしか設定ができないからなんとも言えないんですけど、一日ぐらいは絶対に
8. 全社で「3日」に落ち着くまで
@rChaser53
持っておいた方がいいだろうという話のことは正直な話で思っております。実はnpmレジストリって社内には他にも複数ございまして、だいたい全部で4つぐらい使われてる、つまり私の管理しているもの以外に3つくらいございまして、そこのメンバーと全員話し合った結果、最終的に三日というのにmin-release-ageの方は落ち着いたという話になっております。
@potato4d
おーじゃあこれから三日にする感じなんですね。
@rChaser53
そうですね、私の見ているプライベートnpmに関して言うと、min-release-age相当の機能が提供できてるんですが、その他のレジストリは残念ながらまだ提供ができていないというふうなところがございまして、公式のnpmレジストリでは確かに配信が停止されました。でも
@rChaser53
npmレジストリ側のキャッシュとして残ってしまっています。そのためにインストールが動いてしまいますという問題が発生、実際しまして、この前のAxiosの問題さえもそうなったと。そうなると一日だと問題が発生する可能性があると。
@rChaser53
幸運なことに、インターネットを遮断する方が先に動いてくれたので、間に合ったので、社内としてはトラブルは発生しないで済んだんですけれども、そのことを考えると、一日は心もとない、怖い、危ないという話で、現状min-release-age三日が社内では
@rChaser53
5月20日の時点の全社の数字ですかね。全社の数字って言っても出てから色々な部署にアナウンスされるまでにちょっと誤差があるんであれですが、現状はmin-release-age三日にしようねっていう話に一旦は着地したという話になっております。
@potato4d
あれですね。どんどん攻撃対象が増えるにつれて、攻撃対象が増えるということはメンテが行き届いているもの、行き届いていないものいろいろ出てくるんで、時間がかかるパッケージも増えてはくるんで、より安全に倒していくのがいい感じもしますね。
@rChaser53
そうですね。
9. pnpm という選択肢 — minimumReleaseAgeExclude
@rChaser53
そうですね、個人的な意見で言いますと、正直な話npmを直接使わないでpnpmを使いまして、pnpmであればminimumReleaseAgeExcludeみたいなものがあって、min-release-age相当の機能から
@rChaser53
除外するみたいな感じのことができる。このパッケージのこれだけ除外するよみたいな感じのことができるやつがあるので、それと組み合わせるとより安全な運用ができるのではないかなというふうな気がしております。近況でいうと、そこまで話には出てはいないんですが、0-day攻撃のようなケースが起きてしまった場合、
10. 0-day 対応と min-release-age のジレンマ
@rChaser53
既存の脆弱性を狙われてしまった場合ですね。即座に対応しなければまずい、即座にバージョンアップをしなければまずいってなった際に、このmin-release-ageっていうのはすごい障害になってしまう。一旦min-release-ageを解除しないとそもそも更新ができないみたいな話になってしまうわけですね。
@potato4d
そうですね。
@rChaser53
そういったことは非常に、min-release-ageを解除する最中に他のサプライチェーン攻撃食らっちゃったみたいな感じのこともゼロでもないですし、そういった危険性などを考えますと、一部のパッケージだけmin-release-ageから除外できるよという機能のあるpnpmとかのほうが
@rChaser53
現状のセキュリティの運用としては強いのかなという話は正直思わざるを得ないかなというところです。
@potato4d
なるほど。確かに。
11. デフォルト有効化の潮流と npm 公式の動向
@rChaser53
まあ実際pnpmだとバージョン11からminimumReleaseAgeがデフォルトで一日に設定されているとか
最近だとaubeとかですかね。
あの辺の新しくて生えてきたnpmのCLIとかもデフォルトでminimumReleaseAgeが一日は設定されてるみたいな感じのこともありますので、ちょっとそっちの方がnpmのCLIのセキュリティ事象としては強いのではないかという気は思わざるを得ないながら
@rChaser53
一応フォローの方はしますと、このminimumReleaseAgeExcludeみたいな機能がやっぱり欲しいよ、npm公式でも入れてほしいというふうなissueの方は上がっておりまして、話の方には上がっているので、遅かれ早かれ公式のnpm CLIもそういった機能が出てくるのではないかな
@rChaser53
というふうに思われるのですが、残念ながら2026年5月20日現在、まだその機能はリリースされていないという形になりますね。
@potato4d
確かになんかあれですもんね、そもそもnpm CLI自体がmin-release-ageに対応したのも最近の話ですし、一応npm CLI本体もかなり活発にそのあたりは動いてはくれてるんで、対応してくれる可能性も大いにはありそうですよね。
@rChaser53
そうですね、npmの11.10でしたっけ? 事実上使えるようになったのが確か4月とか3月とかその辺りなんですよね、今年のね。本当に公式のnpmの動きはやはりゆっくりで、過去あまりにもちょっと質が良くなかったから、yarnとかにも取って代わられそうな
@rChaser53
時期があったみたいなものもありますが、サードパーティのCLIの方がやはりそういったものは強いのだなという気持ちがありますね。
@potato4d
そうですね、フットワークの軽さみたいなのはやっぱりそこは違いが出てきますよね。
@rChaser53
そうですね。npmレジストリ自体とかが徐々に徐々にセキュリティを強化しようという動きとかは、公式の方のレジストリ自体が動いてくれているみたいなので、なので、npm自体がそういったセキュリティに対して危機意識を持っていないのかというと、そういうわけではないのかなと思いますが。
@potato4d
そうですね。なるほど。じゃあちょっとしばらくはまたサードパーティの時代がちょっと来つつ、公式の動向を見ていく方がいいって感じですね。確かに最近はpnpmかなり人気ではあったんで、まあスムーズに普段Node.js環境を使ってる人とかはpnpmの方が便利ですし、
@potato4d
安全っていうようなところで使っていきつつ、ただ全体としては全てのCLIツールとかをサポートするべきではあるかなと思うんで、システム的にはしっかり固めていくのが今のいい塩梅かなっていうふうなところですかね。
@rChaser53
そうですね。npxとかは公式のnpmだと便利ですからね。メインでNode.jsとかを使っていない方にちょっと気軽に使ってくれってなるとやっぱりnpxかなみたいな話になる。
@potato4d
そうですよね。
@rChaser53
公式のnpmからはなかなか逃げられない。
@potato4d
ちょっとそこはなんで、まあほどほどに使いつつがひとまずの結論みたいな感じがしますね。
@rChaser53
ちょっと歯切れが悪い感じになってしまうのがそうなっちゃうかなとは思っております。
@potato4d
そんな気はします。ありがとうございます。
12. 個人でできる自衛策 — ignore-scripts
@potato4d
最後にもう一つ聞きたいなと思ってるんですけど、これを聞いている人に対して、もし個人の環境とかでこういうのやっておくといいよみたいなのがあったら、今pnpmを使う、あるいはmin-release-ageをそれぞれで設定するみたいな話が出てきたかなとは思いますけど、それ以外にこういうところを意識しておくといいよみたいなのとか、こういうことやっておくと
@potato4d
自衛に繋がるよみたいなのあったりしますか。
@rChaser53
この辺で一番強いっていうのは、ignore-scriptsとかのオプションを設定するのがものすごい強いんじゃないかなって言わさせておりまして。postinstallだとかのフックのスクリプトを完全に停止するので、これ停止するとほぼ直近のセキュリティの
@rChaser53
サプライチェーン攻撃って大体防げてるので、かなり強いかなという気がしますね。
@potato4d
たしかに。pnpmはそれデフォルトだと実行しないんでしたっけ。
@rChaser53
pnpmはどうだったかな。
@rChaser53
結構なんだかんだ言ってフックで実行するパッケージってまだまだ残っておりまして、なんで割とここをデフォルトでtrueっていうのは割と強気な設定なのではないかと。多分まだpnpmでもfalseなんじゃないかなとか。
@potato4d
ああ。
@rChaser53
ちょっとすいませんね、手元で確認することができないんですけど。
@potato4d
じゃああれですかね、ひとまずはignore-scriptsとかできるので、オフにできるのであればignore-scriptsオフにしても支障が出ないのであればやっておいた方が安全かなってとこですかね。
@rChaser53
そうですね。
@rChaser53
かなり、うん、安全ではないかと思います。
13. クロージング
@potato4d
なるほど。ありがとうございます。ぜひ今日聞いている方は、もしまだmin-release-age設定してないよっていう方がいらっしゃったら設定いただければと思いますし、ちょっといろいろ情報を、状況をウォッチしてできるだけ安全に開発を進めていければと思います。
@potato4d
というわけで、今回は吉澤さんと共にですね、プライベートnpmにおけるmin-release-ageの取り組み、並びに今後npmパッケージを使っていくにあたって、min-release-ageなどなどと向き合っていくべきかというふうなところについて話しました。LINEヤフーのフロントエンド組織ではこのようなフロントエンドに関する議論やディスカッションを日々行っております。
@potato4d
UIT INSIDE内に公開したコンテンツの中には、過去には社内勉強会から始まった企画などもありますので、今後も社内外の情報をどんどん発信していければと思っております。また本ポッドキャストに関するご意見ご感想は、ハッシュタグ「#UIT_INSIDE」でつぶやいていただきますと
@potato4d
スタッフの方で拾わせていただきますので、お気軽にツイートいただければと思います。というわけで、本日は吉澤さんとともにプライベートnpmにおけるmin-release-ageの取り組みについて話していきました。吉澤さん、ありがとうございました。
@rChaser53
ありがとうございました。