- xz攻撃は configure段階でのシェルコード注入 と make段階でのオブジェクトファイル注入に分かれており、この分析では xz 5.6.0・5.6.1 配布 tarball のスクリプトがバックドア用オブジェクトファイルをビルドに紛れ込ませる過程を追跡している
- 悪性コードとオブジェクトファイルは
tests/files の バイナリテスト入力ファイル のように圧縮・暗号化されて隠されており、「手作業で作ったテストファイル」という既存 README の説明が偽装を容易にしていた
m4/build-to-host.m4 に追加されたコードは bad-3-corrupt_lzma2.xz を見つけて tr と xz -d で復元した後 /bin/sh で実行し、5.6.1 には新しいテストファイルから追加スクリプトを探す 拡張メカニズム も入っている
- configure スクリプトは
src/liblzma/Makefile と libtool を書き換え、make 中にも隠されたスクリプトを再実行させ、-z,now と PIC 関連フラグを調整して ifunc resolver が初期動的リンク時点で実行されるようにする
- make段階では
good-large_compressed.lzma から悪性オブジェクトを抽出・復号した後、crc64_fast.c と crc32_fast.c のビルド成果物をすり替え、_get_cpuid 経由で RSA_public_decrypt 呼び出しを横取りする
攻撃の全体構造
- Andres Freund は 2024-03-29 公開の
oss-security@openwall メーリングリストで xz攻撃の存在 を知らせた
- 前日には Debian security と非公開の
distros@openwall リストにも通知
- きっかけは Debian sid のインストールで
liblzma 関連の異常、つまり SSH ログイン時の高い CPU 使用率と Valgrind エラーを見たことだった
- 攻撃は大きく2段階で構成される
configure 中にシェルコードが注入される
- このシェルコードが
make に再びシェルコードを注入し、make 中に悪性オブジェクトファイルをビルドへ追加する
- 悪性オブジェクトファイルを
evil.o のようにリポジトリへ直接入れると疑われやすいため、攻撃者はシェルコードとオブジェクトファイルを バイナリテスト入力ファイル の中に圧縮・暗号化して隠した
tests/files ディレクトリは Jia Tan が現れる前から存在しており、README には .xz、.lzma、.lz デコーダ実装をテストするためのファイル群で、一部は hex editor で直接作られ「ファイルそのものより良いソースコードはない」と説明されている
- 攻撃者はこの文脈を利用して、いくつかの新しいテストファイルを追加するように見せかけた
バックドアが狙った実行地点
- スクリプトの最終効果は、悪性オブジェクトファイルの
_get_cpuid 関数が GNU indirect function(ifunc) resolver の一部として呼び出されるようにすること
- ifunc resolver は通常、プログラム実行中に遅延呼び出しされ得るが、セキュリティ上、動的リンク初期にすべて呼び出して GOT・PLT を読み取り専用でマップする方式が広く使われる
- 悪性 ifunc resolver は GOT・PLT がまだ書き込み可能な初期時点で実行され得る
- バックドアはテーブルから
RSA_public_decrypt を見つけて攻撃者版に置き換える
- 置き換えられた関数は、正しい SSH 証明書が提示されたとき攻撃者コードを実行する
configure段階: build-to-host.m4 の偽装
- xz-utils は GNU autoconf を使用しており、通常
configure と支援 m4 ファイルはソースリポジトリではなく tarball 配布物に含まれる
- 攻撃は xz 5.6.0 と xz 5.6.1 tarball に、想定外の支援ライブラリ
m4/build-to-host.m4 を追加するところから始まる
- 悪性
build-to-host.m4 には標準ファイルと比べてもっともらしい変更が含まれている
- serial を
3 から 30 に上げる
- 著作権年を
2023 から 2023-2024 に変更
- 判別しづらいシェル・m4 の変更をいくつか追加
- 実際の核心は
grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/ で配布物内の特定パターンを探すコードである
- このパターンに一致するファイルは
./tests/files/bad-3-corrupt_lzma2.xz
- 結果として
gl_am_configmake はこのテストファイルを指す
gl_path_map は tr "\t \-_" " \t_\-" に設定され、タブ・空白、アンダースコア・ダッシュを相互に入れ替える
隠された最初のスクリプトの復元
gl_[$1]_prefix はファイル名の最後のドット以降の要素を抽出するため xz になる
- 名前は prefix のように見えるが、実際にはファイル拡張子である
- ビルドマシンにすでに入っている可能性が高い圧縮コマンド名になる
- その後に作られるコマンド文字列は、見た目には
sed "r\n" を使うが、実際には 難読化された cat に近い
sed の r\n は存在しないファイル \n を読もうとする命令なので何も起こらない
-n がないため入力をそのまま出力する
- 実際に実行されるコマンドは次のような形である
cat ./tests/files/bad-3-corrupt_lzma2.xz | tr "\t \-_" " \t_\-" | xz -d
- このコマンドは
AC_CONFIG_COMMANDS を通じて config.status 実行過程で評価される
- 復元された出力には
####Hello#### と ####World#### が見え、README によれば bad-3-corrupt_lzma2.xz の1番目と3番目のストリームは有効な xz ストリームで、中央のストリームだけ LZMA2 データが破損している
5.6.0 と 5.6.1 の違い
- xz 5.6.0 で復元された最初のスクリプトは
good-large_compressed.lzma から特定バイト範囲を切り出して変換した後、raw LZMA ストリームとして展開して /bin/sh に渡す
- xz 5.6.1 の最初のスクリプトには Linux でなければ終了しようとする行が5回含まれる
[ ! $(uname) = "Linux" ] && exit 0
- その後の分析対象となる長いスクリプト内にも 5.6.1 専用の Linux 確認行がある
- その行は
= の前後に空白がなく動作しないバグがある
- 5.6.1 では
head の最終バイト数、tail オフセット、tr 引数が 5.6.0 と異なる
- 例では 5.6.1 は
16×2048+939 = 33,707 バイトを抽出する
- その後
tail -c +31233 で最後の 31,233 バイトを使う
- 抽出パイプラインは次の段階で構成される
xz -dc で good-large_compressed.lzma を展開
head パイプラインで特定バイト範囲を抽出
tail で後半部分を選択
tr で単純置換暗号を適用
xz -F raw --lzma1 -dc で raw LZMA ストリームを展開
- 結果を
/bin/sh で実行
5.6.1 の拡張メカニズム
- 長いスクリプトには、設定されていない変数を
eval する地点が複数ある
- 例:
eval $zrKcVq, eval $zrKcSS
- デバッグ出力用、または将来別のメカニズムで値を設定する拡張ポイントの可能性がある
config.status があれば、スクリプトは LD, CC, GCC, srcdir, build, enable_shared, enable_static, gl_path_map などを読む
- 5.6.1 に新たに入った拡張コードは
tests/files で2つのマジック文字列を探す
- 開始文字列:
~!:_ W
- 終了文字列:
|_!{ -
- 2つの文字列が同じファイル内にあれば、その間のバイトを抽出し、
tr と raw LZMA2 展開を経て出力物を eval する
- このメカニズムは、後から既存のバイナリテストファイルを再生成したという理由を作らずに、別のテストファイル内へ新しいスクリプトを入れるための構造に見える
configure段階の実行条件
- スクリプトはバックドアに必要な条件が揃わなければ静かに終了する
- GNU ifunc サポート が有効である必要がある
config.status に ["HAVE_FUNC_ATTRIBUTE_IFUNC"]=" 1" が必要
config.h に define HAVE_FUNC_ATTRIBUTE_IFUNC 1 が必要
- 共有ライブラリビルドが有効である必要がある
enable_shared が yes であること
- ビルド対象は x86-64 Linux である必要がある
build が ^x86_64 と linux-gnu$ 条件を満たすこと
- CRC ifunc 関連ソースがそのまま存在している必要がある
crc64_fast.c
crc32_fast.c
crc_x86_clmul.h
- コンパイラとリンカ条件も確認する
GCC=yes
CC=gcc
LD -v 出力に GNU ld を含む
- バックドア入りテストファイル
good-large_compressed.lzma と bad-3-corrupt_lzma2.xz が必要
Makefile と libtool の改変
debian/rules があるか、RPM_ARCH=x86_64 なら configure段階で src/liblzma/Makefile を改変するコードが実行される
- まず Makefile 内に、後で挿入地点として使う複数行が存在するか確認する
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__uninstall_files_from_dir = {
am__install_max =
am__vpath_adj_setup =
am__include = include
all: all-recursive
LTLIBRARIES = $(lib_LTLIBRARIES)
AM_V_CCLD = $(am__v_CCLD_$(V))
libtool には pic_flag=" -fPIC -DPIC" があるか確認する
- その後
sed -i で Makefile の各所に次のような性質の行を散りばめて挿入する
am__test = bad-3-corrupt_lzma2.xz
am__strip_prefix = tr ...
am__dist_setup = ... | xz -d ... | $(SHELL)
am__test_dir = $(top_srcdir)/tests/files/$(am__test)
am__test_dir は名前上はディレクトリに見えるが、実際にはファイルを指す
- 追加された行は一か所に集められず、Makefile 全体の各所に挿入され、生成された Makefile がもっともらしく複雑に見えるように構成される
リンカフラグと再帰実行
- configure段階のスクリプトは
liblzma_la_LDFLAGS に -Wl,--sort-section=name,-X を追加する
- 既存
LDFLAGS に -z,now または -z -Wl,now がなければ -z,now も追加する
-Wl,now は動的ローダにプログラム開始時点ですべてのシンボルを解決させ、LD_BIND_NOW 動作を強制する
- この過程で ifunc resolver が起動時に実行される
- バックドアは GOT・PLT がまだ書き込み可能なときに実行され得る
libtool の PIC フラグは次のように変わる
- 既存:
-fPIC -DPIC
- 変更:
-fPIC -DPIC -fno-lto -ffunction-sections -fdata-sections
- スクリプトは
AM_V_CCLD と長いシェル断片も Makefile に追加する
- 最後には
sed rpath $(am__test_dir) | $(am__dist_setup) を実行する
sed rpath も難読化された cat の役割を果たす
- 結果として make 中に次のようなパイプラインが再実行される
cat ./tests/files/bad-3-corrupt_lzma2.xz |
tr "\t \-_" " \t_\-" |
xz -d |
/bin/sh
make段階: オブジェクトファイル抽出
- make段階では
src/liblzma ディレクトリでスクリプトが再実行される
config.status が現在ディレクトリにないため configure段階の Makefile 編集部分はスキップされる
- 代わりに
.libs/liblzma_la-crc64_fast.o と .libs/liblzma_la-crc32_fast.o があれば make 中だと判断し、次のコードを実行する
- 5.6.1 には make段階用の拡張フックも新たに入っている
- 開始文字列:
jV!.^%
- 終了文字列:
%.R.1Z
- 該当文字列を持つテストファイルはなく、将来拡張用の構造に見える
- CRC ifunc 関連ソースが想定どおりか再確認する
- configure段階で追加したコンパイル・リンカフラグが適用されているかも確認する
../../libtool に追加 PIC フラグが必要
liblzma_la_LINK に -z,now または -z -Wl,now が必要
lazy が含まれていれば終了する
悪性オブジェクトの復号と選別
- スクリプトは
gettext.m4 の内容に応じて2つのオフセット値のいずれかを選ぶ
- 配布された xz tarball の
gettext.m4 には検査文字列がないため、例のビルドでは入力全体を使う
good-large_compressed.lzma を再び展開し、先に設定された head パイプライン i で 33,707 バイトを抽出する
- その出力をバイト単位に分割した後、
awk で RC4類似の復号関数 を実行する
- 5.6.1 版では2番目のループが 8192 まで反復する
- 5.6.0 版では同じ位置のループが 4096 まで反復する
- 復号された出力は
xz -dc --single-stream で再び展開される
--single-stream は最初の xz EOF マーカーで停止し、先に tail で抽出した領域を読まないようにする
- 最終結果は
liblzma_la-crc64-fast.o に書き込まれる
CRC オブジェクトのすり替え
- スクリプトは実際のビルド成果物
.libs/liblzma_la-crc64_fast.o を、似た名前の .libs/liblzma_la-crc64-fast.o にバックアップする
- アンダースコア (
crc64_fast) とハイフン (crc64-fast) の差を利用する
- 続いて
crc64_fast.c に sed で加えた変更をコンパイルし、抽出した悪性オブジェクト liblzma_la-crc64-fast.o を一緒に入力して .libs/liblzma_la-crc64_fast.o を上書きする
- 挿入される C コードは
_is_arch_extension_supported を新たに作り、その内部で _get_cpuid を呼び出す
- 既存の
crc64_resolve は is_arch_extension_supported() の代わりに _is_arch_extension_supported() を呼ぶよう変更される
_get_cpuid はバックドアオブジェクトファイルが提供する関数で、cpuid 情報を返す前に追加動作を行う
- 特に GOT・PLT を書き換えて
RSA_public_decrypt 呼び出しを横取りする
crc32 側の処理と後始末
- crc64 改変が成功すると、スクリプトは
crc32_fast.c にも類似の改変を適用する
- crc32 側にはバックドアオブジェクトファイルを追加しない
- ビルドにバックドアオブジェクトを二重に入れないため
- なぜ crc32 と crc64 の ifunc を両方横取りするのかは明確でない
- どちらか片方だけでも十分に見えると分析されている
- デバッガ上で2つのディスパッチコードが似て見えるようにした可能性がある
- 2つのコンパイルが成功すると
liblzma_la_LINK で .la ファイルを再リンクする
- リンクに成功しても
.libs/liblzma.so がなければ失敗とみなし、バックアップを復元する
- 成否にかかわらず
.libs/liblzma.a, .libs/liblzma.la, .libs/liblzma.lai, .libs/liblzma.so* を削除する
- その後 Makefile の元のリンク段階が再生成すると想定している
- 失敗経路ではバックアップした crc32・crc64 オブジェクトを元の名前に戻す
- 最後に一時・バックアップファイルを削除し、make成果物へ悪性オブジェクトを注入しつつ痕跡を残さないよう動作する
1件のコメント
Hacker News の意見
長年 autotools を嫌ってきた立場からすると、今回の件は自分の立場を正当化してくれたと言いたいところだが、マルチプラットフォームをサポートするほど複雑なビルドシステムなら、誰かがこういうものを紛れ込ませられるほど不可解にならざるを得ない
それでも、多くのソフトウェアが、実質的に誰も全体を理解していない巨大なカーゴカルト的シェルスクリプトでビルドされているのは本当に問題だ
ビルドスクリプトが Python で書かれていたなら、バックドアを難読化するのははるかに難しかったはずだ。変なコードであることが誰の目にも明らかだっただろうから。bash のコードは読めなくても、単に正常なものだと見なされがちだ
./configure && make && make installで済んでいた時代が懐かしいその流れに対するベストプラクティスが完全に欠けていることが複雑さの根なので、こうした条件では
mybuild.tomlのようなビルド設定ひとつで解決できるものではないそれに、圧縮ライブラリのように本質的には数学とメモリ割り当て程度を行うだけのものをビルドするのに、なぜ複雑なシステムが必要になるのかも疑問だ
開発者として驚くし、私の目には最上級の攻撃手法に見えるものでも、このレベルで活動している人たちにとっては、おそらく初中級の難易度なのだろうということを示している
HN に投稿されるものの中には、これよりはるかに高いレベルのものもあるので、十分なお金や他のインセンティブがあれば可能なことの始まりにすぎないと思う。GitHub 上の膨大なパッケージと数百万のライブラリを考えると、このベクトルはあまりに効果的で、今後数か月のうちに似た事例が何百件も明らかになると確信している
Philips Hue から Alexa、SumUp、カメラメーカー、Netgear、TP-Link まで、コンシューマー/プロシューマー向けハードウェア企業が心配だ。製品の中はオープンソースライブラリでいっぱいで、ほとんどの開発チームがこうした密かな注入ベクトルを探すことに時間を使っていないと 100% 確信している
信頼性を掲げる商業組織なら、依存関係を採用する前にサプライチェーン分析を行う。だから通常、安定した Linux ディストリビューションの維持のために Red Hat にお金を払い、FreeBSD のようなプロジェクトが標準インストールに含めるソフトウェアを強く制限しているのだ
今回の件で影響を受けたのなら気の毒だが、それはあなたの責任だ。無料のビールのようにタダで使っているソフトウェアの開発者が突然豹変するのを心配するなら、そうしないインセンティブを提供する、つまりお金を払うか、あるいはプロジェクトをフォークして自前のセキュリティ対策を上乗せすべきだ
商用ソフトウェアの依存関係でサプライチェーン攻撃が起きることを心配するなら、その被害補償を含む契約を交渉すべきだ。その意思がないならプロとは言えない
付け加えると、SSH のような最も基本的な依存関係でさえ、サプライチェーンを点検すべきだと真剣に言っている
初期の情報セキュリティ記事もコードの一部しか説明できず、攻撃の全体戦略までは扱えていなかった。攻撃とコードが洗練されていたからだ。初期の分析が互いに違う形で攻撃を説明していたのも、理解するのが単純ではなかったからで、後になってようやく「ついにリモートコード実行攻撃に見える」という趣旨の記事が出てきた
今ではサーバー上で脆弱性を検出するスキャナーまで出てきたので、皆が「ああ、あれはあまりに単純で愚かな攻撃だったのに、なぜもっと早く見つけられなかったのか」と言えるようになっただけだ
これはすべての機器に同じように当てはまる。Android が古いカーネルを使わなければならないのも嫌だし、macOS が古びた Darwin/BSD 系を動かしていたのも気に入らなかった。バックポートに必要な労力が心配だ
もちろん、オープンソースに脆弱性がないという意味ではない
むしろ、ほとんど発見されることのないプロプライエタリソフトウェア内部の見えないバックドアをもっと恐れるべきかもしれない
Thomas Roccia のインフォグラフィックが、まだここで言及されていないようだ: https://twitter.com/fr0gger_/status/1774342248437813525
たとえば oss-fuzz は GitHub リポジトリを直接クローンして xz をビルドしていた。バックドアはリポジトリではなく tarball にだけあったので、oss-fuzz がバックドアを発見する可能性はなかった。したがって、その oss-fuzz PR はバックドアとは無関係な本物の変更だった可能性もある
Andreas Freund の周辺で、バックドアが公開されることをもっと早く知った別のアカウントや人物がいた可能性はどの程度あるのだろうか。今でも周辺に別の内通者がいる可能性も考えてしまう
.gitignoreファイルに無視項目を追加することから始まっている。最近はこういうものを検知するのが難しい素朴な傍観者の立場でいちばん目立つ部分はこれ。
「多くのファイルはヘックスエディタで手作業で作られているため、ファイルそのものより優れた『ソースコード』は存在しない」。liblzma のようなパース用ライブラリでは、そういうこともあり得るのは理解できる。攻撃者は、単に新しいテストファイルをいくつか追加しているように見えたのだろう。
ファイル自体が怖いのは確かだが、理由はわかる。それでも少なくともビルドからは切り離せるのではないか。
「通常、configure スクリプトとサポートライブラリはソースリポジトリではなく、tarball 配布物にのみ追加される。xz の配布もこの方式だ」。
autotools に対する儀礼的な怒りはさておき、なぜ tarball にテストファイルが入る必要があるのかわからない。悪意あるテストが開発者のマシンを感染させる可能性もあるだろうが、tarball が最終成果物をビルドするためのものなら、必要なものだけを含める方針であるべきではないか。特にテストファイルが監査不能なバイナリの塊ならなおさらだ。
ただ、自分たちが最後にそうしたときは upstream Git を優先し、必要な autoconf の生成物は自分たちで生成していた。Git にない内容が入ったリリース tarballという概念は、ずっと好きになれなかった。
対象マシンでコードをコンパイルした後、テストを実行できる必要がある。
「1つ目の違いは、スクリプトが Linux 上で実行されていない場合、必ず、きわめて確実に終了するようにしている点だ」。
繰り返しのチェックは確かに謎だ。私の仮説では、攻撃者は圧縮ライブラリのテスト入力らしく見えるように、繰り返しを入れたのかもしれない。
あるいは単に手抜きだったのかもしれない。
意図的に見えるが、なぜ存在するのかはわからない。xz が入力が短すぎたり複雑でなかったりすると圧縮をスキップするような挙動をするため、サイズを埋める目的で追加したのかと思ったが、削除してから xz で再圧縮しても正しく圧縮され、元の平文は圧縮アーカイブのバイト列に残らなかった。
Git にコミットされた
.xzファイルの正確なバイト列を再現しようとしてわかったのは、そのスクリプトの xz ストリームはデフォルトの xz プリセットで圧縮されたものではなさそうだということだ。xz --lzma2=dict=65536 -c stream_2を使わないと再現できず、デフォルトの番号付きプリセットはいずれも別の辞書サイズを選んでいた。これも意図的に見えるが、理由は理解できなかった。繰り返しがなければ、圧縮ファイル内にセキュリティツールやアンチウイルスに引っかかる奇妙なバイナリが生じていた可能性もある。
現代の技術が極悪なほど複雑で、不必要に不可解になっているのは悲劇的に笑えるし、ますます悪化している。開発者たちはサディスティックにそれを楽しんでいるように見える。
私たちが作る製品の複雑さが増していくのに合わせて、ツールが追随しているのはかなり驚くべきことだ。正直なところ、ほとんどの場合は単により単純になっているだけで、人々が新しいものを学びたがらないことに近いと思う。
このプロジェクトに侵入させるためにこの人物たちを雇った誰かは、長期間検知を逃れられるようにするために、とてつもない時間を費やしたはずです。幸い、あまりに複雑だったため、すべての要素を考慮しきれませんでした
だからセキュリティの面では、オープンソースは常にクローズドソースより優れていると思います。もちろん今回の事件は、サプライチェーンの巨大な欠陥を明らかにし、FOSSの基盤要素がいかに過小評価され、メンテナーが操作に対して脆弱であるかも示しました
しかし同じ攻撃が民間企業の中で起きていたら? 高度な難読化すら必要なかった可能性が高いです。十分に大きなPRと迫る締め切りがあれば、最小限の労力でこうしたものを運用システムにこっそり入れられます。会社が何が起きたのかに気づくころには、すでに犯罪人引渡条約のない国へ飛び、Torやダークウェブで流出データを売っているでしょう
民間企業に採用されれば、会社はあなたが誰なのかを知っています。それ自体が怪しい行為を防ぐ即時の抑止力です。GitHubでは、あなたが誰なのか誰も知りません。見つからずにプロジェクトへバックドアを入れるのはより難しいかもしれませんが、見つかっても負うリスクはありません。望むだけ何度でも試せます。Jia Tanはいまだに捕まっておらず、犯罪人引渡条約のない国で暮らすために人生全体を設計する必要もありませんでした。もともとそういう場所にいるのでなければ、ですが
そしていったん入った後でも、対象プロジェクトに好き勝手にコミットできるわけではありません。マネージャーとその上のマネージャーには別の優先事項があります。営利企業のしばしば機能不全な管理は、むしろここでは抑止力として働きます。コード自体を正当化しなければならないだけでなく、そもそもなぜその作業をしていたのかも説明しなければなりません
関係がぎくしゃくしている国でも、政治的に都合がよければ交渉の一部として引き渡すことがあります。ロシアも、Snowdenが国家機密を暴露したのでなければ、拘束し続けなかった可能性が高いです。ただの普通のデータ流出だったなら、別の場所でマネーロンダリングで捕まったオリガルヒと捕虜交換していたかもしれません
リストを作るだけでも有用でしょう
今回の事件から得られる教訓は、重要なオープンソースプロジェクトの中核的な貢献者に匿名性を認めるべきではないのかもしれない、ということです。この攻撃は成功し、攻撃者はおそらく何の代償も払わずに逃げ切るでしょう。匿名だったからです
そのような措置は役に立たないでしょうし、国家主体やそれに類する高度持続的脅威にとっては、攻撃段階に身元詐称を1つ追加するか、バックドアが発見されても保護できる要員を使えばよいだけなので、簡単に回避できます
一方で、そのような手続きに必要な技術的ハードルは、オープンソースコミュニティ全体に大きな損害を与える可能性が高いです
ここでの解決策は、この攻撃から学び、似た攻撃をより難しくする慣行へ変えることです。リポジトリにないファイルは、リリースtarballに絶対に入れるべきではありません。その結果生成されたコードはすべてチェックインすべきで、ビルドスクリプトは派生コードを再生成したうえで、チェックイン済みのコードと異なれば失敗すべきです。理解しにくいデータはリリースビルド過程からアクセスできないようにすべきで、バイナリデータに依存するテストはリリースバイナリと完全に分離してビルドすべきです
まず、特にセキュリティ分野の重要な貢献者の多くは、正当な理由から仮名での活動を好みます。身元公開を強制すれば、彼らを遠ざけることになります
次に、多くの人が推測しているように情報機関が背後にいるなら、そのような機関はいずれにせよ「本物」の身元を作り出せます。結局、役に立つ人は排除し、攻撃者は排除できないことになります
政府が関与しているなら限界はありません。唯一の方法は、信頼できる場所に物理的に出頭するよう求めることですが、その場所が攻撃者の管轄権下でないことを願うしかありません
誰かがライブラリを作り、他の人たちが使い始めたら、身元公開を強制されるのでしょうか? メンテナーは報酬を受け取るのでしょうか?
クローズドであれオープンであれ開発の仕事をしたことがあるなら、開発者たちが半ば怠惰にPRをそのまま承認することを知っているはずです。Linus Torvaldsは、一日中問題を指摘する珍しい例外に近い存在です
誰かが実際に細かく気を配るほど厳格だと、その人は開発を妨げる厄介者と見なされがちです。細かいことを指摘するという理由でチームとの緊張が生まれます
打ち明けると、今の私にも似た状況があります。厳格なのは私ではなく、私が雇った開発者の1人です。残念ながら、彼の綿密な行動は良く評価されず、チームから外さざるを得ませんでした。東欧出身で、フィードバックを非常に率直に伝える傾向があることも助けになりませんでした
Unixユーティリティは長い間検証されてきました。カーネルと中核ユーティリティは固定し、変えないでほしいです。本当に必要でない限りは
壊れていないなら直すな、ということです。ソフトウェア帝国が制御不能に見えます
時にはきちんと作られた輝かしい例もありますが、全体としてはそうしたものが完全に押し流されたと見るべきです