【ITニュース解説】PunyGuard: A Chrome Extension That Blocks Every Internationalized Domain
2026年10月16日に「Dev.to」が公開したITニュース「PunyGuard: A Chrome Extension That Blocks Every Internationalized Domain」について初心者にもわかりやすく解説しています。
ITニュース概要
PunyGuardは、視覚的に区別しにくい国際化ドメイン名(IDN)によるホモグラフ攻撃を防ぐChrome拡張機能だ。`xn--`を含む全てのIDNへのアクセスを問答無用でブロックし、フィッシング詐欺からユーザーを保護する。正当な日本語ドメインも対象とするが、これは確実な防御のため設計された厳格なトレードオフである。
ITニュース解説
ウェブの世界には、一見すると本物そっくりなのに、実は悪意のある偽サイトへ誘導する「ホモグラフ攻撃」という巧妙な手口が存在する。例えば、apple.comという有名なサイトのアドレスに酷似したаррӏө.comのようなドメイン名がある。これは、見た目は同じ「apple」に見えても、使われている文字が全く異なる、キリル文字などの非ASCII文字で構成されたドメインだ。現在のブラウザには、このような紛らわしいドメインを検出し、その実体を「Punycode(ピュニコード)」という形式(xn--で始まる文字列)に変換して表示する機能がある。これにより、ユーザーは騙されにくくなるはずだった。しかし、ブラウザが用意する紛らわしい文字リストに載っていない文字が使われた場合、この対策は簡単にすり抜けられてしまう。人間が注意深く見ても、一文字の違いを見分けるのは非常に困難であり、この問題は解決しにくい。
このような背景から開発されたのが、Chrome拡張機能「PunyGuard」だ。PunyGuardは、曖昧な判断を一切せず、明確なルールに基づいて国際化ドメイン名(IDN: Internationalized Domain Name)をブロックする。IDNとは、日本語やキリル文字など、ASCII文字以外の文字を含むドメイン名のことで、これらはインターネットの内部ではPunycodeというxn--で始まるASCII文字列に変換されて扱われる。PunyGuardの設計思想は、「見た目で判断しない」という点に集約される。ブラウザの判断基準である「似ている文字リスト」は、世の中に膨大な種類の文字が存在し、フォントによって見え方も変わるため、完璧なリストを作るのは不可能だ。そのため、PunyGuardは、ドメイン名がPunycode形式であるかどうか、つまりホスト名の中にxn--で始まる部分があるかどうかだけをチェックする。これにより、正規の日本語ドメインなども一律でブロックされるが、これは作者が「マシンに間違えさせない」という明確なルールを与えるために、意図的に受け入れたトレードオフである。作者自身が日本語ドメインを好まないという個人的な信念も、この設計を後押ししている。
PunyGuardの実装は、ChromeのdeclarativeNetRequest (DNR) APIという仕組みを利用している。これは、拡張機能が事前にルールを登録しておけば、ブラウザ自身がそのルールに基づいてネットワークリクエストを処理するというものだ。PunyGuardは、^https?://(?:[^/?#]*[.@])?xn--という一つの正規表現をDNRに登録する。この正規表現は、URLのホスト名部分にxn--で始まるラベル(ドメイン名の.で区切られた各部分)が含まれる場合にマッチする。これにより、例えばаррӏө.comのようなドメインが入力されても、内部でPunycodeに変換されたxn--80a6aa68c8d.comという形式でブラウザが処理するため、この正規表現に引っかかってブロックされる。ホスト名のみをチェック対象とし、URLのパス(/以降の部分)などは対象外とすることで、一般的なサイトの利用を阻害しないように配慮している。
ブロックされた際、PunyGuardはユーザーにChrome標準のエラー画面ではなく、拡張機能が用意した専用の警告ページを表示する。これにより、ユーザーは何が起きたのか、なぜアクセスがブロックされたのかを明確に理解できる。この警告ページを表示するためには、Chrome拡張機能が<all_urls>という全てのウェブサイトへのアクセス権限を必要とする。これは比較的広範な権限だが、PunyGuardはこの権限を利用して警告ページへのリダイレクトのみを行い、ユーザーが閲覧するページのコンテンツを読み取ったり、外部にデータを送信したり、何かを保存したりすることは一切ない。このような設計の意図や、なぜこの権限が必要なのかは、READMEに明記されており、透明性を確保することでユーザーからの信頼を得ようとしている。警告ページには、元のURL、UnicodeとPunycodeの両方で表示されたホスト名、そしてそこに含まれる非ASCII文字のリストが表示され、ユーザーは目で確認できない文字の正体を知ることができる。この警告ページ自体も、悪意のある文字列が入力されることを想定し、表示する全ての情報をエスケープするなど、セキュリティに最大限配慮して設計されている。
セキュリティツールとして最も避けたいのは、「壊れていても誰にも気づかれないサイレントエラー」だ。PunyGuardの開発においては、このサイレントエラーを防ぐために多くの工夫が凝らされた。例えば、DNRで使う正規表現はJavaScriptの正規表現エンジンとは異なるRE2というエンジンで解釈されるため、JavaScriptのテストが通ってもDNRではエラーになる可能性がある。これを防ぐため、PunyGuardは実際のChromeブラウザを動かすE2Eテスト(End-to-Endテスト)の中で、Chrome自身に正規表現がサポートされているかを確認させている。また、拡張機能が正しく動作していない場合や、ユーザーが意図せずサイトアクセス権限を制限してしまった場合などには、ツールバーのアイコンに警告バッジを表示し、問題があることをユーザーに明確に伝える仕組みも備えている。意図的に許容しているいくつかの弱点(例えば、URLのユーザー名部分にxn--が含まれる場合の誤判定や、シークレットウィンドウでの挙動の違いなど)についても、その理由とともにドキュメントに記載し、透明性を確保している。
PunyGuardは、AI(人工知能)を積極的に活用して開発された。コードの記述、テストの作成、さらにはコードレビューの多くをAIが担った。AIは、様々な選択肢とそのコストを提示する能力に優れている。しかし、PunyGuardの設計における最も重要な「決定」、例えば正規の日本語ドメインもブロックすることや、シークレットウィンドウでの問題への対処法など、最終的な方針を決定したのは人間である作者自身だ。どのトレードオフを受け入れるか、利用者の状況を理解し、その痛みを評価できるのは人間だけだ。これらの決定事項とその理由、検討されたが却下された選択肢は、ADR(Architecture Decision Record)などのドキュメントに記録され、AIとの協業を効率化すると同時に、将来の自分にとっても重要な情報源となる。また、AIが作成したコードやテストを鵜呑みにせず、外部アプリからのリンクやブラウザの言語設定変更、シークレットウィンドウでの動作など、自動テストでは検証しにくい部分は、最終的に作者自身が実機で動作確認を行った。AIは開発者の手と目を増やすツールであり、何を構築し、何を諦め、そしてそれが本当に機能するかを決定するのは、依然として人間の役割である、という哲学がPunyGuardの設計と開発全体に貫かれている。
PunyGuardは、検出の賢さを追求するのではなく、「判断しない」というシンプルかつ明確な一つの決定を下し、その実行を疲れることのないマシンに任せるという道を選んだ。これは、複雑な状況を人間が理解し判断するのではなく、シンプルなルールに基づいて機械に任せることで、ミスをなくし、信頼性を高めるという考え方だ。PunyGuardはChromeウェブストアでは公開されず、GitHubで配布されている。これは、作者自身のためのツールであり、他者からの機能要求に応えないという作者の意思の表れでもある。日本語ドメインを使用せず、ホモグラフ攻撃によるフィッシング詐欺に不安を感じるユーザーにとっては、この拡張機能は非常に有効な選択肢となり得るだろう。