要約

  • 現在のAFRINIC WHOIS Cryptページは、type="text"のパスワード欄を持ち、plaintextpasswordという名前で同一オリジンへPOSTするフォームを宣言している。本調査では値を入力せず、フォームも送信していない。
  • BCRYPTの出力だけでは、生成前の入力を誰が扱ったかは分からない。しかもAFRINICの会員向けガイドは、AFRINICと共有するのはハッシュだけで、平文パスワードは会員が安全に保持すべきだとしている。両者を結ぶ処理境界の説明が必要だ。

セキュリティの説明は、しばしば完成した文字列から始まる。BCRYPT-PWの形式を示し、それをWHOISのauth:属性に置けばよいと教える。しかし、運用上の権限は完成品だけに宿るのではない。ハッシュになる直前の一瞬に、元のパスワードがどこにあり、誰の管理下を通り、何に複製され得るかが決まる。完成したハッシュには、その経路を語る欄がない。

AFRINICの公開資料は、調べる入口を明示している。WHOIS utilitiesページはBCRYPT-PW生成ツールを案内し、別ホストのWHOIS Cryptアプリケーションへリンクする。2026年9月14日に取得した同アプリのHTMLでは、フォームの識別子はmyForm、メソッドはPOST、アクションは相対指定の?lang=en#cliである。「Password」というラベルに結び付く入力欄はtype="password"ではなくtype="text"で、idと送信名の双方がplaintextpasswordになっている。送信ボタンの表示は「Generate hash」だ。

これは公開された命令の静的な観察であり、動作試験ではない。本調査では実在の認証情報も、試験用の秘密も入力していない。ボタンを押さず、通信を傍受せず、サーバー側のAPIを呼ばず、WHOISオブジェクトも変更していない。したがって証拠が示すのは「このフォームがブラウザーに何をさせる設計か」であり、「ある送信が実際に完了した」「値が保存された」という事実ではない。

HTML標準は、この設計を読むための基準を与える。フォームは利用者が値を与えるコントロールの集合で、その値は処理のためサーバーへ送られ得る。標準の開発者向け説明も、HTTP POSTの本文にパラメーターを載せてサーバー処理へ渡す例を示す。このページのアクションは相対URLなので、通常の解決先は現在のwhois-web.afrinic.netオリジンである。つまり、利用者が宣言どおりにフォームを実行すれば、ハッシュ前のアプリケーション値をAFRINIC側の受信点へ渡す構造になっている。

ここで「平文」という語を慎重に扱わなければならない。ページのURLはHTTPSである。TLSは経路上の盗聴や改変を防ぐための仕組みであり、取得した資料にはパスワードがネットワーク上を読める状態で流れると示すものはない。本稿でいう平文は、ハッシュ化前のアプリケーション値という意味だ。TLSで暗号化された通信路を通って受信サーバーに届くことと、端末内だけで計算することは別の設計である。

同様に、受信したことと保存したことも別だ。サーバーが値を短時間だけメモリーに置き、BCRYPTを計算し、ログにもトレースにも残さず破棄する実装は十分に考えられる。反対に、汎用のプロキシ、例外収集、分析基盤が明示的な除外設定なしに要求内容を複製する可能性も、一般論としてはある。だが本調査はサーバーコード、プロキシ設定、ログ、保持領域、事故記録を見ていない。どちらの実装かを断定できない。

それでも受信境界を記事にする理由は、AFRINIC自身の会員向けガイドにある。maintainerオブジェクトの説明では、会員に平文パスワードからBCRYPTハッシュを生成するよう勧めている。そのうえで、AFRINICと共有すべきなのはハッシュ値だけであり、平文パスワードは会員が安全に保持すると明記する。

この文言には穏当な読み方がある。「共有」とは最終的なWHOISオブジェクトへの登録を意味し、auth:に元のパスワードを書かないという指示なのかもしれない。その範囲なら、サーバー側で一時的に生成するツールとも両立し得る。しかし、普通の利用者が「ハッシュだけを共有する」を、元の値は自分の端末から出ないという意味に受け取ることも自然だ。ガイドが終点を説明し、ツールが途中の受信を宣言しているのに、二つをつなぐ説明がない。

これは矛盾の有罪判定ではない。法令違反、プライバシー侵害、虚偽表示を示す証拠でもない。問いはもっと限定されている。「共有しない」とは、データベースに保存しないことか、計算後に保持しないことか、それとも端末外へ送らないことか。三つは異なる管理目標であり、同じ言葉だけでは保証できない。

入力タイプは、さらに小さな設計判断を見せる。HTMLでtype="password"は機密情報を入力するための状態で、入力表示を隠すコントロールになる。取得ページは通常のtype="text"を使う。これは肩越しに誰かが見た証拠ではなく、漏えいや侵害の証明でもない。BCRYPTの強度、コスト、ソルトについても何も示さない。ただし、ブラウザーにパスワード用のマスキング動作を指定していないという事実は残る。

仮にtype="password"へ変更しても、問題全体は解けない。表示を隠すこと、HTTPSで運ぶこと、受信端で処理すること、ログから除外することは、それぞれ別の制御だからだ。画面上の見え方を改善しても、POST先は変わらない。鍵アイコンを目立たせても、受信後の寿命は分からない。

ブラウザーで動くスクリプトも境界に含まれる。取得したHTMLはchallenges.cloudflare.comからCloudflare Turnstileを読み込み、ローカルパスのjQuery、Mustache、main.jsも読み込む。OWASPの第三者JavaScriptに関する指針は、外部から供給されるコードを、変更統制と機密データの両面で独立したリスクとして扱う。ページ内で実行されるコードは文書の文脈に触れ得るからだ。

ただし、その一般的なリスクモデルを個別の事件へすり替えてはならない。Turnstileのスクリプトタグが存在することは、Cloudflareがplaintextpasswordを読んだ、受け取った、保持した、外部送信したという証拠ではない。必要なのは能力の境界を説明することで、ベンダーを証拠なしに加害者扱いすることではない。

リンクされたローカルmain.jsの静的確認からは、別の誤解を除ける。取得版にはmyForm、plaintextpassword、BCRYPT、Cryptフォームの生成処理が見当たらない。スクリプトはcreate-containerという別のWHOISオブジェクト編集画面があるときにビューを初期化し、テンプレートの読み込み、属性編集、オブジェクト保存を扱う。そこで扱う編集用パスワードと保存先は、Cryptフォームの欄とは別物である。

したがって、このmain.jsを「ブラウザーで先にハッシュしている証拠」と呼ぶことはできない。一方で、同じ静的確認を「すべてのクライアント処理が存在しない証拠」に広げることもできない。他のライブラリー、Turnstileの将来版、ブラウザー拡張、動的応答、サーバー側処理は確認対象外だ。一つのファイルが参照していないという事実には、一つのファイル分の重さしかない。

AFRINICの現行プライバシーポリシーは、肯定的な統治材料を提供する。AFRINICを管理者として位置付け、WHOISサービスを情報収集面の一つに挙げ、指定職員にアクセスを限定し、第三者に保護義務を課し、組織目的または法的要件に沿って保持期間を定める。こうした約束を無視して「何の規則もない」とするのは不正確だ。

しかし、全体方針はCryptフォーム固有の処理記録ではない。要求本文をリバースプロキシが記録するか、エラー時に引数が残るか、観測基盤がサンプルを取るか、サポート用の診断情報に値が入るか、平文がメモリーに何秒残るか、外部スクリプトが欄へ到達できるかは分からない。政策は責任を定めるが、個別経路を自動的に証明しない。

ログは、最も測りやすい確認点である。OWASPのログ指針は、認証パスワードを原則として直接記録すべきでない情報に含め、必要なイベントでは削除、マスキング、無害化、ハッシュ化または暗号化を検討するよう求める。本調査はAFRINICのログを一行も閲覧していないため、実際に記録されているとは主張しない。代わりに、公開されているフィールド名を試験可能な条件にできる。plaintextpasswordの値は、アプリケーションログ、プロキシログ、トレース、分析イベント、例外、サポート資料に残らないべきだ。

正常系だけの確認では足りない。ハッシュが正しく返る場合には慎重に値を捨てていても、タイムアウト、入力エラー、Turnstile失敗、アプリケーション例外、上流拒否の際に共通エラーハンドラーが本文を記録することがある。これはAFRINICに起きていると述べているのではない。処理記録が成功と失敗の両経路を対象にすべき理由である。

BCRYPTの出力一致も、保管証明にはならない。同じ合成入力から期待される形式が得られれば計算の一部は確認できる。そこから、分析基盤が値を複製しなかった、スクリプト権限が分離された、再試行キューに残らなかった、担当者が診断データを読めなかった、とは推論できない。暗号計算の正しさと入力経路の最小化は独立した評価項目である。

整合的な設計は二つ考えられる。第一はブラウザー内でのローカル生成だ。監査可能なコードを公開し、依存関係と完全性を管理し、機密欄を第三者スクリプトの権限から隔離し、外向き要求に元の値が含まれないことを示す必要がある。「local」と表示するだけでは証明にならない。

第二はサーバー生成を維持することだ。その場合は、AFRINICのエンドポイントがHTTPSで新規かつ再利用されていないパスワードを受け取り、ハッシュ計算のためだけに短時間処理し、ログやトレースから除外し、平文を保持せず、処理者のアクセスを制限すると明記する。リモートであること自体が欠陥なのではない。受信者、目的、寿命、禁止される複製を利用者が確かめられるかが要点だ。

会員向けガイドも選択した設計に合わせるべきである。「ハッシュだけを共有」はWHOISオブジェクトの最終値だけを指すのか、生成経路全体を指すのかを明示する。後者ならリモートPOSTは合わない。前者なら一時処理の規則を続けて説明すればよい。いずれの場合も、現用または他サービスで再利用するパスワードを生成器に入力しないという警告が必要である。

処理記録は、機密な構成を公開することと同義ではない。最小限でも、計算が端末かサーバーか、要求本文を記録しないか、平文をいつ破棄するか、第三者コードから入力欄を隔離するか、という四点は外部へ説明できる。実装の詳細を伏せながら、利用者が自分の保管判断に必要な境界を示すことは可能だ。

また、記録には版と日付が要る。フォーム、Turnstile、プロキシ、エラー収集、分析基盤のどれかが変われば、古い確認は新しい経路を保証しない。変更のたびに合成値で再検証し、公開説明が実装と同じ版を指すようにする。この小さな同期がなければ、ガイド、法務文書、コードがそれぞれ正しくても、利用者に届く約束は一つにならない。

さらに、「保証」と「観測」を分けて記録する必要がある。「パスワードをログへ書かない」は組織の保証であり、許可された合成マーカーが列挙した各保存先に現れないことを確かめるのは特定版に対する観測である。保証は責任を示し、観測は実装との対応を示す。どちらも未来の全版を永久に証明しないが、日付と対象を持つ二つの資料は、由来を語れない最終ハッシュより強い。

未確認項目も明示すべきだ。正常応答しか試していないなら、タイムアウトや例外は対象外と書く。アプリケーションログだけなら、プロキシや外部分析まで結論を広げない。現行main.jsの静的確認だけなら、他のスクリプトを保証しない。空白を公開することは弱さではなく、限定された証拠が流通の途中で過大な安全証明へ変形するのを防ぐ統制である。

この方法なら、変更時の再検証も狭くできる。フォームの型だけが変われば表示と送信の宣言を、プロキシが変わればログ排除を、Turnstileが変われば文書内の能力境界を確認し直す。影響を受けた部分だけを再試験し、変わっていない証拠は保持する。サービス全体を漠然と「安全」と呼ぶより、どの版のどの経路を誰が確認したかを示す方が、利用者にも運用者にも役立つ。

最終ハッシュと処理記録の役割も分けるべきである。ハッシュは計算結果を示し、WHOISオブジェクトへ複製できる。処理記録は入力経路を示し、サービス運用者が版ごとに維持する。正しい出力だけから、確認していない保管経路を逆向きに推定してはならない。

この区別は、問題が見つからなかった場合にも価値を持つ。合成値がどの保存先にも現れず、スクリプト境界も説明どおりなら、その結果はAFRINICにとって強い肯定的証拠になる。監査の目的は欠陥を作ることではなく、現在は説明されていない性質を、利用者が依拠できる事実へ変えることである。

資料