ディスカッション (77件)
皆さん、またもやcrates.io でサプライチェーン攻撃 が発生しました。コミュニティとして、この問題に真剣に向き合うべきタイミングが来ているのではないでしょうか。
現在、crates.io は基本的に開発者が自由にクレートを公開・維持する「プッシュ型」モデルで運営されています。このオープンな環境は非常に価値がある一方で、今後はオプションとして「プル型」モデル、つまりコミュニティによる厳格な審査とレビューを経て追加・更新されるキュレーションされたエコシステムがあっても良いのではと考えています。
イメージとしてはDebianの「Stable」と「Unstable」のような関係性です。エンドユーザー側の開発者が、自身のニーズに応じて信頼性と安定性のプロファイルを自由に選択できる仕組みです。
Rustエコシステムにおいて、このようなモデルの導入は技術的に実現可能でしょうか?また、crates.io 側ですでに何らかの計画があるのか、あるいは状況が悪化する前にもっと良い解決策はあるのでしょうか?
そんな動き、物流的に無理だよ。cratesチームにはそれを実現する資金も人手も全然足りてないし。
まあ理屈はわかるけど、これってワークフローの刷新にかかる資本とか、監査の運用コストに関係してる話かな?あと、Linuxディストリビューションごとのパッケージマネージャーはどうやってそういう作業をこなしてるんだろう?予算がもっと大きいのかな(Linuxディストロがどう経済を回してるのかよく知らないんだけど)。Rustを使ってる大企業がこういう動きに関心を持つことはあると思う?
予算がもっと大きいのかな(Linuxディストロがどう経済を回してるのかよく知らないんだけど)。
Debianには開発者とメンテナー合わせて約1,200人のアクティブな貢献者がいるんだよ。
ちなみにcratesチームは6人だ。
気合でコード書く「バイブコーディング」を極めれば、その数字なんて実質同じようなもんよ!(皮肉)
「バイブコーディング」で突き進むなら、そもそもセキュリティなんて気にしてないだろ。
待って、お前らセキュリティなんてあったの? #ミーム#
気合いを入れてコードを書けば、自分で自分をサプライチェーン攻撃することだってできるぞ!いや、待てよ...
cargo vet って聞いたことある?
まさにOPが求めてたツールって感じだね。
しかもMozilla製とは、いいじゃん!
これが脇道に逸れたワークフローのままだと、Debian stableみたいに広く普及することはないだろうね。だから穴もたくさん残る。あと、最後のリリースが2024年って…これってもう機能完結してるってこと?
脇道に逸れてるとは思わないよ。僕が知る限り、Googleみたいなところが依存関係を検証するのに使ってるはずだし。
あと、それが機能完結とみなされているとしても驚きはないね。
crates.ioでの最後のリリースは4ヶ月前だよ。
ありがとう、GitHubのリリースしか見てなかった。
私の理解が合ってるか確認させて:
cargo-vetの認識だと、依存関係が受け入れられるようになるのは基本的に2通りだよね。信頼できる誰かが監査したか、自分で監査したかのどちらか。つまり、このシステムは「自分が信頼できる監査ソースの数」と「その人たちのレビュー能力」がボトルネックになるってことだよね。ってことは、マイナーなライブラリ群が網羅されることは一生ないんじゃないかな。
何か見落としてる点はある?
公平に言わせてもらうと、それは解決策とは呼べないけど、何もしないよりはマシだよね。
ここで言及されてるクレートなんて多くても16ダウンロードくらいだし、とりあえず大丈夫でしょ。
もう少し冷静に議論しよう。
今回の件が特に大きな影響を与えなかったのは事実。
crates.ioのチームが現状、こうした問題に十分対処するリソースを持っていないのも事実。
でも、今の状況がいつ大事故になってもおかしくない綱渡り状態であることもまた事実なんだ。
完璧な解決策があるわけじゃないけど、この問題を矮小化するのはやめようぜ。
そうとも言えるし、そうでもない。レジストリにはセキュリティのための仕組みが色々とあるし、外部企業が公開レジストリをスキャンしまくってるから、何でもないようなcrateを使って『様子見』をしてることが多いんだ。何が網をくぐり抜けて、何が引っかかるのかをテストしてるのさ。攻撃者は何が通過できるのかを把握したら、次は有名だったりダウンロード数の多いcrateに対して同じ手口を仕掛けてくるってわけ。
これは表面積の問題なんだよね。パッケージの一つが人気のあるリポジトリに紛れ込んだ瞬間、すぐに大きな問題になり得る。しかも、それが意図的じゃない場合もある。悪意のある人間が、実際に重要なバグを修正するPRを送ってきて、ついでに例のパッケージを紛れ込ませたら? そしてレビューで見過ごされたら? 全然あり得ない話じゃないよ。
小さな標準ライブラリとcrates.ioの設計ミスは、Rustエコシステムの2つの醜い失敗だよ。設計段階からそうなってる以上、直ることはないだろうね。
いつか、もっと健全なエコシステム設計を備えた、Rustより優れた言語が出てくるはずさ。
それまでは、依存関係をベンダー管理して自分で抱えるしかない。他に方法はないよ。
追伸:今、もっと大きなリスクが浮上してる。LLMを使ったコード貢献が、tokioのような基盤パッケージにまで受け入れられ始めてるんだ。
まさに破滅への三位一体だね。
Rustをプロダクションで使う機会が増えるほど、C言語に対してネットで言われるほどの劇的な改善があるとは思えなくなってきた。C++と比較しても、言語仕様が肥大化し続けている現状ではトントンか、それ以下かもしれない。先行言語が抱えていたエコシステムの課題は、Rustでもそのまま続いているしね。結局のところ、依存関係が深すぎて全容を把握するのが非常に困難という問題が解決されていない。Cargoで解決しているわけではなく、せいぜい隠蔽しているだけで、ある意味その方が厄介だ。ビルドシステムの拡張をRustで書くのがCMakeより進化しているとも思わないしね。Spackのように、まともな依存関係ソルバーを実装したエコシステムツールの方がよっぽど役に立つ。今なら自分の全プロジェクトで、完全に管理されたエコシステムを簡単に構築できるし。プロジェクトの各バージョンから要件を切り離せるから、新しいパッケージがリリースされた時の破壊的変更にも対応できる。Rustだと、コード自体に問題がなくても依存関係側の変更でビルド不可になるケースがあるし、リリースソースにロックファイルが含まれていないと本当に詰む。
あと、AIによる粗悪なコンテンツが蔓延しているのも痛いね。技術の世界が、何をしているのか分かっていない人たちが吐き出したゴミで溢れかえっているよ。
[削除されました]
笑った。君と一緒に低評価を食らいに来たよ。誰かがより良いエンジニアリングのために踏ん張らなきゃいけないからな。
その髪色、最高だ!自分はハゲちまったから、髪でおしゃれを楽しめる人たちを羨ましく思いながら生きていくよ :)
Rustという言語は、メモリ安全性だけじゃなく、CやC++と比べても圧倒的に優れているよ。
確かにエコシステムには欠点もある。でも、世の中で最も忌み嫌われているビルドシステムと言ってもいいCMakeよりは、Cargoの方が100倍マシだ。それに、ソースからのビルドを嫌ってディストリビューションのパッケージマネージャーに頼りたくないという意見があったとしても、結局今のモダンな言語は全部この方式に落ち着いているわけで、そっちの方が圧倒的に楽だからだよ。問題がないとは言わないけど、それらはRust特有の悩みってわけじゃない。
このモデルを採用している他のエコシステムに対する愚痴は消しちゃったけど、Cargoだけじゃないのはその通り。でも、『みんなやってるから』っていうのはレミングの論理だし、説得力があるとは思えないな。CMakeが一番恐れられてるのは、単に一番使われているからだよ。同じようにCargoのbuild.rsもひどいものだと思うけど、今のところは苦しみの種になるようなものが少ないだけ。CMakeはCargoがやることの半分しか担ってないし、YAMLを使うSpack(こっちにも問題はあるけど)や、Pythonを採用したConan(これはまあ、選択肢の一つとして)みたいなものもある。ビルドシステムってのは基本的にどれもクソだよ。誰も関わりたくないけど、誰もが抱える問題を解決しなきゃいけないんだから。ビルドシステムをよく扱う身としては、一番恐ろしいのはBazelだね。Mesonは基本CMakeと変わらないけど、Pythonへの依存があるのが個人的に好きじゃない。CMakeはソースからビルドすれば非常にシンプルなツールチェーンで済むし、依存関係のほとんどをベンダーとして取り込める。Boost buildやAuto toolsを挙げれば、CMakeが夢のように思えるよ。うまく書かれたCMakeとCargoはほとんど同じで、ターゲット、ターゲットタイプ、依存関係の記述になる。CMakeは他にもインストールの場所やCpackの構成も聞くけど、すべてが常に静的とは限らないからね。それ以外はツールチェーンの指定が全てだよ。Cargoは楽で、基本的にシンプルなオプションがあるソースが一つだけ。CMakeは10種類以上の言語の奇妙な仕様や、複数のコンパイラなんかを扱わなきゃいけない。でも、そのほとんどは別ファイルのツールチェーンで完全にカスタマイズできる。本当に例外的な場合を除いて、CMakeでif文や関数を多用する必要なんて滅多にないよ。まあ、例外的な場合にはbuild.rsが必要になるのと同じようなものさ。
いや、CMakeが現状こうなってるのはC++のエコシステムに慣習がないからだよ。慣習がない以上、ユーザーが調整しなきゃいけない設定項目を山ほど用意するしかないんだ。他のビルドツールを使ったとしても結局同じ問題にぶち当たるよ。どのエコシステムも、かろうじて耐えられるレベルのツールしか持ってないってことじゃないかな。
言語が広く使われるようになった後にビルドシステムを作る場合は特にそうだよね。Rustの開始当初からCargoが利用できたというのは非常に大きなアドバンテージだよ。RustプロジェクトをビルドするのにみんながCargoを使っているわけだから。
CMakeの設定項目はほとんどコマンドラインかツールチェーンファイルで操作すべきだ、というのが私の主張なんだ。Cargoも同じことをやっているけど、依存関係に対してかなり独善的な見方をしているから隠蔽されているだけだよ。そうじゃない場合は build.rs に醜いコードを書かなきゃいけない。だから実際には「優れている」わけじゃなくて、ほとんどのRustプロジェクトがCargoと付き合うためのコストを払っているに過ぎないんだ。
要するに、Cargoは問題を「解決」しているわけじゃなくて、ほとんどのプロジェクトから悩みの種を隠しているだけなんだ。Cargoという象牙の塔の外で作業したい人にとっては、結局同じ苦しみをすべて引き受けなきゃいけないんだよ。
ビルドツールの本質的な複雑さはどれも大差ないよ。Cargoが使いやすくてシンプルなのは、強力な規約に基づいているからだね。依存関係はcargoから、バイナリはsrc/main.rs、ライブラリはsrc/lib.rsにある、といった具合に。そういう規約がないと、cmakeみたいに何千もの細かい設定を指示しなきゃいけなくなる…まあ、Rustのコンパイラはプロジェクト内のファイルを自動検知できるからcmakeよりはマシだけどね。CやC++のコンパイラにはそれができないから。
とはいえ、規約の範囲外に出ると途端に厳しくなるのは確か。まあ、それが規約の存在意義でもあるんだけどね。
実際、RustにはCargo以外のビルドツールを使うユーザーにとって厄介な点が一つある。CargoはRustプロジェクトをビルドするための公式レイヤーであって、それより下の階層(コンパイラのCLIとか)は実装詳細とみなされているんだ。だから、いつでも仕様が変わる可能性がある!実際にはそんなこと滅多にないけどね。
っていうか、RustのstdlibはCのstdlibより大きいし、Cargoは単に依存関係を扱いやすくしただけだよ。Cで依存関係が少なく見えるのは、(a)動的リンクのせいで依存関係が見えなくなっている場合があるのと、(b)依存関係を追加するのがあまりに面倒すぎて、自分で書くかコードをコピーした方がマシっていう理由が大きい。「ツールを使いにくくする」のが解決策とは思えないな、たとえ実際には多少の効果があったとしても。Cargoは単調な作業を減らしているだけで、根本的な問題に悪影響を与えてるわけじゃない。
Cargo.lockファイルをコミットしないのは開発上の悪手だし、それに対する解決策はすでにある。
AI生成のゴミについては同意。中身をチェックせずに、危ない依存関係を紛れ込ませたAI生成のPRが混ざるリスクは相当なものだし、いつ大きな事件が起きてもおかしくない。
a)は半分正解だけど、SpackやNix、あるいはRustのエコシステムを上から制御するようなパッケージマネージャーが何とかしてくれるはず。b)についてはa)の解決策を見てみて。あと経験上、Rustの非OSSコンポーネントを扱うのもめちゃくちゃ大変だよ。
君の言う通りだね。特に本格的な開発において、標準ライブラリが充実しているのは時間短縮にもなるし、本当に助かる。ソフトウェアの選択肢や自由度が高いのは良いことだけど、ソースコードと作者が信頼できて、車輪の再発明をしなくて済むという安心感の中で構築できるのはやっぱり最高だよ。
stdに詰め込んだからといって、魔法のようにそれを検証するためのリソースが増えるわけじゃないからね。
crates.ioでこの方向性の計画はあるのか、状況が悪化する前にもっと良いアイデアはないのか?
最初の緩和策がすでに入り始めてるよ。cargoの設定で最小時間を設けるやつで、公開されてから最低X時間/日経過していないクレートのバージョンを使わないようにするんだ。
かなり軽量な機能だけど、公開から利用までの間に人間が対応できる時間的猶予が生まれるんだよ。
- 新リリースを通知されたメンテナーが、自分たちがリリースした覚えがないことに気づいて、そのバージョンをyank(取り消し)する時間ができる。
- 自動スキャナーが新しいバージョンをチェックしてアラートを出し、そのアラートに対処するための時間ができる。
- ...
年齢制限(age cutoff)の設定はいつ安定版(stable)で使えるようになるの?
さあね :)
特定の機能にしっかりした期限が設けられることはまずないから、「6週間から8週間で」って言いたくなるね^1。
RFCは承認されたから、進捗を追いたいなら Tracking Issue をフォローしておくといいよ。Cargoの主要なコントリビューターの一人がすでに対応を引き受けていて、すでに作業用のブランチもあるみたいだし。
今すぐその機能を使いたいなら、cargo-cooldown っていうCargoプラグインで使えるらしいよ。
^1 Jeff Atwoodへの敬意を込めて。
これセキュリティに関連する部分だから、チームとして優先度上げて対応したほうがいいと思う。プロセスがどうなってるかは全くわかんないけどね。
優先順位を上げるべきという点には同意するけど、チームは主にボランティアで運営されているんだ。だから、優先順位を上げる唯一の方法は、誰かが自ら進捗のために働きかけることしかないね。
もしやる気があるなら、プロジェクトは歓迎するはずだよ。ヒントが必要なら rust-lang Zulip や cargo contributor's guide をチェックしてみて。さらに、Issueを見た感じだと ehuss や waihanglo にコンタクトを取ってみて、どう協力できるか聞いてみるのがいいかも。
もっと早く進捗させる別の方法は、企業(または自分自身)に開発者を雇ってもらって、フルタイムでその問題に取り組んでもらうことだね(資金調達ページ を参照してみて)。
確認してみるよ、ありがとう。
もしそうしたいなら、プロジェクトは助けを歓迎するよ
それ、自分でも試した?僕の経験だと、rustcやclippyへのコントリビュートは簡単だったけど、cargoへのコントリビュートは不可能に近かったよ。
Cargoに最小待ち時間を実装したとしても、みんな揃って14日に設定するだけだよ。コミュニティが変更をチェックする時間を確保するため、なんて言いながらね。結局14日間は誰も中身を確認しないし、審査なんて行われない。問題が解決されたんじゃなくて、先送りにされただけ。しかも発見までの猶予期間が14日増えるだけさ。この解決策はただのチキンゲームで、問題を他人に押し付けて誰かが何とかしてくれるのを待ってるだけだね。
僕が挙げた2つのポイントに対して、そんなに丁寧な返信をくれて嬉しいよ(皮肉だけどね)。
念のため、提案を全体的な文脈で理解してもらえるように伝えておくと、Cargoにはすでに評価目的でバージョンを公開するための慣習があるんだ。
リリース候補を公開するなら、Cargo.tomlのバージョンにハイフンを使ってプレリリース識別子を追加すればいい。よくあるパターンはこんな感じ:[stackoverflow]
• 0.1.1-rc.0 (リリース候補0)
• 0.1.1-rc.1 (リリース候補1)
• 0.1.1-beta.0 (ベータリリース)
• 0.1.1-alpha.1 (アルファリリース)
プレリリースバージョンはCargoによって自動的にインストールされることはない。ユーザーがCargo.tomlで明示的にその識別子を指定してオプトインする必要があるんだ。
これによって、ユーザーが誤って不安定なバージョンを取り込むことを防ぎつつ、テストしたい人にはテストできる環境を提供できる。安定版リリースの準備ができたら、-rc サフィックスなしでバージョン 0.1.1 を公開すれば、それがユーザーに届くデフォルトのバージョンになる。
だから、セキュリティ上の懸念がある場合にプレリリース版を公開することを妨げる理由は何もない。その後、有志の魔法のようなツールでバグが見つかれば、同じコミットハッシュを使ってリリース版を公開すればいいわけだ。
既存の慣習を利用もせずに、中途半端で練り込みの足りない解決策を持ち出しても、エコシステムに遅延と不確実性を増やすだけだよ。問題を先送りにして、誰かが解決してくれるのを待ちながら時間を無駄にするようなものだからね。
ポイントは新しいコードに潜む潜在的なバグを避けることじゃなくて、意図的に悪意を持った更新を押し付けてくる乗っ取られたクレートを回避することだよ。
攻撃者が悪意のあるアップデートを公開するとして、わざわざプレリリースバージョンなんて使わないでしょ。
そうやってセキュリティベンダーがスキャンする時間を作って、マルウェアを検知したという実績で名声を稼ごうとしてるだけじゃないの。
この機能が入るとこれらのベンダーへのキャッシュフローが減るから、面倒なことになるかもね。
最初の対策として、最小経過時間の構成設定がCargoに導入されつつあるね。公開からX時間や日数が経過していないクレートは使わないように設定できるやつ。
クレートの公開者が任意でアップデートの「理由」を設定できるようにして、そのメタデータをcrates.ioで配布してくれると嬉しいかも。だって、もし新しいバージョンがセキュリティ修正のためのものなら、設定した最小期間とか関係なくすぐに調査したいからね。
「理由」なんてものがあっても、悪意のある連中には何の意味もないよ。
だからこそ、その場でアップデートするんじゃなくて「精査」するべきだって言ったんだよ。Cargoの最小時間を設定するくらい用心深いなら、悪意のあるやつがフラグを立てたタイミングでアップデートして、その用心深さを自ら台無しにするようなことは避けるべきでしょ。
今回のケースならcargo auditを使ってみたらどうかな?
うまくいけば、依存関係にセキュリティアップデートがあって「アップグレードすべきだ」って教えてくれるよ。cargo auditに自動修正させるか、手動で対応して設定済みのx日間の遅延を上書きすることもできる。
もちろん、これらはメンテナ本人や他の誰かがcargo auditにセキュリティ上の問題や修正を報告してくれることが前提だけどね。
君が提案してたやり方と手間は変わらないと思うけど、修正内容と「理由」を一緒に通知できる分、こっちのほうがスマートだと思うよ。
依存関係の古さをチェックして、新鮮すぎるものにはエラーを出す、CI用の小さなバイナリを作ったよ。こういう攻撃を防ぐ単純な方法の一つで、もちろん全部防げるわけじゃないけど、発見される前に素早く拡散させるタイプの攻撃には有効かな。
ツール名はcargo-quarantine。完璧というよりはPoC(概念実証)だね。cargo自体にこの機能を追加するIssueも立ってるけど、自分が知る限りまだ統合はされてないはず。
あとcargo-cooldownっていう別アプローチのツールもあるよ。自分のはCIで実行するリンターに近いけど、cooldownの方は新鮮すぎる依存関係を積極的にダウングレードするラッパーって感じ。
uvの exclude-newer = "30 days" みたいに、リポジトリ全体やプロジェクト単位でパッケージの依存関係に最小経過日数を指定する方法ってある?
bunやnpmでもできればいいんだけど。これでサプライチェーン攻撃を完全に防げるわけじゃないのは分かってるけど、個人的にこういう設定があるのは結構安心感があって好きなんだよね。
ざっと調べた感じは見当たらなかったけど、中継ぎの対策としては良さそうなんだけどな。
悪いけど、この「攻撃」はちょっと馬鹿げてるよ…少なくともRustの世界ではね。だって対象のプロジェクトにはREADMEもなければ何をするものかも書かれてない。ソースコードを見ても、中身が何もないプレースホルダー構造体があるだけ。ビルドの手順も、curlで何かを引っ張ってきて実行してるのが一目瞭然で、難読化する気配すら皆無だ。
一体誰がこれを動かすんだ?「誰も実行しないような明らかに悪意のあるコードを公開して、オープンソースの重大な欠陥を警告しよう」みたいな、釣りか何かにしか見えないんだけど。
それらは初心者の試みかもしれないし、もっと巧妙な攻撃者が『何が網にかかって、何がそのまま通り抜けるのか』を確認するための偵察かもしれない。結局、僕たちが知ることができるのは、運悪く(あるいは運良く)網に引っかかったものだけなんだから。
それと、AIが依存関係だとハルシネーションを起こしそうなパッケージ名を登録しようとする試みかもしれないね。
これはテストなんだよ。最初は無害な『攻撃』で偵察して、警戒心を解かせようとするんだ。(君もやられたわけだね)。その後で、もっと巧妙で成功率の高い本番の攻撃がやってくるのさ。
目的はトップレベルの依存関係にこっそり紛れ込ませることじゃない。何か役に立つライブラリに追加して、依存関係の依存関係として潜り込ませるほうが近いかな。
Underhanded C code contestと(短命に終わった)Underhanded Rust code contestを紹介したいんだけど、これを見ればいかにして疑われないようにマルウェアを忍び込ませるか、さらには悪意がないかのように見せかけてバグとして紛れ込ませるのが可能かってことがよくわかるはず。
https://www.underhanded-c.org/
だから、特定の攻撃がダメだったとしても、他の攻撃手法は非常に巧妙になり得るってことだよ。
こういう攻撃の狙いは、まさに「バイブコーダー(雰囲気だけでコードを書く人)」たちをターゲットにすることなんだよ。プロジェクトでAIエージェントに依存関係を何でもかんでも使わせながら、それがなぜ必要なのか、どうやって検証すべきかといった知識を一切持っていないような人たちね。結局、一番狩りやすいところを狙ってるってわけ。
貼ってくれたリンクは、自分たちがサプライチェーン攻撃を解決できると主張したい企業による宣伝だよ。でも彼らはまず、問題を大げさに言わないといけないからね。実際のところ、ビジネスを盛り上げるために彼らが怪しいクレートをわざと公開した可能性だって否定できない。
これについては前にも議論されたけど、そんなに単純な話じゃないし、すべてを解決する魔法のような方法はないよ。攻撃ベクターが違えば対策も変わってくるから。
今回のは、紛らわしい名前の新しいパッケージが悪用されたケースだね。前に議論された解決策のひとつにネームスペースの導入があるけど、それならユーザーが公式と非公式のパッケージを見分けやすくなるかもしれない。
検証済みパッケージのグループを分けるやり方は、いくつか問題があるよね。
- 誰が検証するの?ボランティア?十分な人数が集まる?それに、検証する側を誰がチェックするの?
- もしそのグループの規模が小さければ、結局誰も使わなくなるから意味がない。仮に新しいパッケージへの攻撃があったとして、制限されたセットを使っていない人だけが被害を受けるなら、何の対策にもなってないことになる。
お前らCrates使ってんの?真のデベロッパーなら依存関係は自分でベンダー管理しなよ。
コミュニティによる厳格な精査とレビュー
今現在責任を負っているメンテナ以外に、何十万ものCrateと数百万ものリリースをレビューする人なんてどこにいるんだ?なぜ実際のメンテナよりも、そんなレビューアーの方を信頼できるんだ?
Rustのエコシステム全体に対して「何が安全か」を決定する、高い権限を持った新しいアカウントを導入するようなものだぞ。ハッカーは今でも影響力を最大化するために、大規模パッケージのメンテナを狙っている。高い権限を持つレビューアーのアカウントがもし乗っ取られたら、史上最大のサプライチェーン攻撃としてRustのエコシステム全体が壊滅するだろうね。それじゃあ核心的な攻撃ベクトルを解決するどころか、攻撃対象領域を増やしてレバレッジを与えてるようなもんだ。
権限の高いレビュアーアカウントが乗っ取られたとして、どうしてそれが気づかれないなんてことがあり得るの?信頼されたレビュアーなら、自分が標的になりやすいことを理解していて、それに応じて脅威モデルもアップデートしているはずでしょ。
まあ仮に、すごく優秀な攻撃者が信頼されたレビュアーを気づかれないように乗っ取ったとして、さらにレビュー済みのパッケージまで気づかれないように改ざんできたとしよう。それって今と全く同じ状況じゃん!むしろ今のほうが、信頼できるレビュアーすら存在しない分、乗っ取られたパッケージがスルーされる可能性が確実に高いんだよ(誰もレビューを仕事にしてないんだから)。だから今の状況のほうが、信頼されたレビュアーを置く場合よりも実際に「悪い」と言えるんじゃない?
追記:みんなの警戒心が薄れて、結果的に乗っ取られたパッケージがスルーされやすくなるリスクはあるかもしれないね。もしかしたら。でも現実問題として、コミュニティがやってるパッケージの精査って、専門家チームが仕事としてやるレベルに達してるのかな?
コミュニティによる厳格な精査とレビュー
要するに「誰か他の奴がやってくれ」ってことだよね。
言いたいことはわかるし、そうなればいいとは思う。でも問題はこれだ。君は無料のソフトウェアを求めているだけじゃなく、誰かに膨大な追加作業を押し付けようとしてる。誰がやるの?報酬は出るの?その人たちの信頼性や審査内容で本当にセキュリティが向上するのか?
crates.ioのCrateをほんの少し手動でチェックするだけでも膨大な作業量になる。その作業に君は対価を払うつもりはある?
Crateの作者はOSSの慣習に従って作品を公開するインセンティブがある。でも、自分に何の利益もない他人の作品をレビューする作業なんて、単調で面倒でミスも起きやすい。
どんなOSSにも言えるけど、依存関係を検証する責任は君自身にある。それをするリソースがないなら、他人のコードを使うべきじゃないかもしれない。プログラミングは高価なスキルであり、OSSを使っている時点で君は何かを無料で享受している。誰かにお金を払うか、自分でやる覚悟がない限り、何かを要求する立場にはないと思うよ。
代替案として、crates.ioで認証済みユーザーがパッケージのバージョンに「既知の良品」や「既知の不良品」というフラグを立てられるコミュニティ主導の検証システムなら現実的かもしれない。ただ現実には、ダウンロード数やリリースの頻度を見たり、cargo vetを実行したりするのと大差ない。みんな最低限の努力としてそれくらいはやってるしね。ただ、ソーシャルエンジニアリング攻撃に対してはそれでもかなり不完全だけどね。
自動的に調査を実行できるような、分散型の信頼の輪(web-of-trust)システムを構築して検証を行うというのは、大きな前進だね。
Rustはもっと強力な保護策を採用すべきだと思う。NPMにはこういうのが山ほどある し、ワームそのものも含まれているしね。
OpenClawはリリース以来1日あたり2.6個のCVEを記録 しているわけで、全体としてツール経由でハッキングされる人が増えていると言える。
私の知る限り、DebianのStable版とUnstable版の比較はレビューの代わりにはならないよ。AppArmourプロファイルを更新するくらいなら別だけど。遅延についても同様で、アーリーアダプターが気付くまでの猶予ができる程度の意味しかないかな。
真の「レビュー」っていうのは、レビューを投稿するための何らかのプロセス、例えばレビュアー本人やその雇用主を認証するような仕組みが必要なんじゃないかな。
公開時の2FA(二要素認証)を任意で導入すれば、APIトークンが ~/.cargo/credentials.toml にあるだけという状況を防げるかもしれないね。
https://github.com/theupdateframework/rust-tuf も当然役に立つはずだよ。
真の「レビュー」っていうのは、レビューを投稿するための何らかのプロセス、例えばレビュアー本人やその雇用主を認証するような仕組みが必要なんじゃないかな。
それはまさに「cargo vet」がやっていることだね。
それはエンタープライズ領域の懸念事項で、通常はプライベートレジストリを用意して、公開レジストリからの新しいバージョンや新しいcrateを検証した後に取り込むようなパイプラインを構築することで解決されるものだよ。これはパッケージマネージャーのスコープ外であることがほとんどだね。パッケージマネージャーは通常、パッケージの公開セキュリティ情報を取得するためのツールを提供することで支援する立場だから。
各企業が独自のプライベートレジストリを持つべきだと言ってるのか、それとも誰かが立ち上がって、検証済みパッケージの「プライベート」レジストリを作り、企業にアクセス権を販売すべきだと言ってるのかよく分からないけど、もし後者なら君に同意するよ。
ぶっちゃけサプライチェーン攻撃の解決策はもう分かってると思うんだよね…今はどうやって実装するかって段階だよ。君が言ったようなことと、ブロックチェーンによる承認やコード認証局を組み合わせれば、この問題は簡単に終わらせられるはず。
ドメイン向けに公開鍵証明書を発行する認証局があるのと同様に、コードに対しても脆弱性スキャンや検証を行う「公開コード認証局」を作るんだ。今のコードスキャナーが警告を出すみたいに、彼らの承認一つひとつがパッケージバージョンの信頼値に大きな重みを持つようになる。
小さなライブラリなんかは、ドメインの公開証明書と同じように、認証サービスに対して年間利用料を支払う仕組みにする。その料金さえ払えば、認証局が新しいコードバージョンを無料で検証してくれるっていう感じ。
今の公開鍵基盤と同じで、あくまでオプトイン・オプトアウト方式にすればいい。もし会社が利用しないと決めても、これまで通りにリリースすることはできるけど、高い信頼値は付かないだけだ。さらに企業が自社でコードを認証したり、企業間で相互に認証し合うことだって可能だろうね。
この投稿はsocket.devのスパムだよ。誘導を目的とした投稿だ。
Cargoには他にも問題 があるよ。Rustは重要なインフラに導入され始めているから、攻撃者にとって格好の標的になる。個人的には、コミュニティはこの事態に十分備えていないと思うし、Cargoの依存関係地獄はそのうち痛い目を見ることになるはずだよ。
Rustのパッケージマネージャーって、個人的にはエコシステムの中で一番意味不明な部分なんだよね。システムレベルのエコシステムに、どうしてWebエコシステムと同じような仕組みを持ち込もうと思ったのかさっぱり理解できない。npmなんて最近脆弱性が見つかりすぎて、もはやゴミ溜めみたいなもんだし。
できるだけクレートは使わないようにしてる。君もそうしたほうがいいよ。