不可視文字ディテクタ
テキストを貼り付ければ、ディテクタが見つけた不可視 Unicode 文字をすべてハイライトします。ゼロ幅スペース、結合文字、方向制御マーク、ソフトハイフンをそれぞれコードポイント付きで表示します。
このツールが検出する文字
ディテクタが探す一般的な不可視 Unicode 文字と、それぞれが実際に何をするのか
改行候補位置を示します。識別子の中に仕込むと、表示通りには比較されなくなります。
アラビア語やペルシャ語などの筆記体で文字の結合を防ぎます。不可視ですが、隣接するグリフのつながり方を変化させます。
絵文字の ZWJ シーケンスをつなぐ糊です。家族絵文字は 3 つの U+200D で 4 つの絵文字をつなぎ、1 つのグリフとして描画されます。
可視グリフなしで左から右のテキスト方向を強制します。混在方向テキストでは正当な使い道がありますが、bidi スプーフィングにも悪用されます。
右から左の方向を強制します。U+200E と同じ二面性があり、ヘブライ語やアラビア語では必要ですが、フィッシングでも武器化されます。
その位置で行が折り返されるまで不可視で、折り返されるとハイフンとして描画されます。PDF からのコピーで意図せず混入することがよくあります。
不可視文字が実際の問題である理由
不可視 Unicode 文字には正当な目的があります。改行制御、筆記体の結合、双方向テキスト、任意ハイフネーションなどです。しかし、何も描画しないという性質ゆえに、悪用の道具にもなります。Trojan Source 論文(CVE-2021-42574、2021 年 10 月公開)は、双方向オーバーライド文字を使えば、ソースコードが画面で読むのとは異なる挙動でコンパイルされることを示しました。併せて公開された CVE-2021-42694 は、関数名のラテン文字 a(U+0061)をキリル文字 а(U+0430)で差し替えるホモグリフ攻撃を扱いました。日常に近いところでは、ゼロ幅文字がユーザー名や識別子に仕込まれ、同じに見える 2 つの文字列が異なるものとして比較されるケースがあります。コードポイント単位でこれらの文字を浮き彫りにするディテクタが、最も早く見つける方法です。肉眼では見えないからです。
何の役に立つか
本格的なスイープで探すべきもの
上に挙げた 6 文字が最も一般的ですが、全体像ではありません。徹底したスイープは複数の範囲をカバーします。ゼロ幅フォーマット文字の U+200B 〜 U+200F は、改行候補、結合文字、方向制御マークを含みます。U+2060(word joiner)や U+FEFF(バイトオーダーマーク、ストリーム途中に出現した場合)もゼロ幅です。双方向オーバーライドブロック、すなわち U+202A 〜 U+202E と U+2066 〜 U+2069 が、Trojan Source が悪用する対象です。U+00AD(ソフトハイフン)は折り返しまで不可視です。ハングルフィラー U+115F と U+3164、点字ブランク U+2800 は何も描画しないながらセルを占有するため、平然と内容を隠すのに使われます。紛らわしい文字(confusables)の検出は関連しつつも別の問題です。キリル文字 а とラテン文字 a はどちらも可視なため、文字ディテクタには引っかかりません。これを扱うには、Unicode の confusables データに対するチェックが必要で、見た目が同じ文字を正規化されたスケルトンに写像します。
ディテクタをうまく使うには
チェックしたいテキストだけを貼り付けます。すべてブラウザ内で動き、何もアップロードされません。
色分けで文字種をひと目で区別できます。ZWSP は赤、ZWJ は緑、RLM はオレンジ、といった具合です。
検出後に「削除」をクリックすれば不可視文字をすべて取り除き、「クリーンなテキストをコピー」でサニタイズ版を取得できます。
ユーザー入力由来のユーザー名、スラッグ、識別子は、保存・比較する前に必ずチェックしてください。
文字列比較が失敗し、両者が同じに見える場合は、両方をここに貼ってください。原因の大半は隠れた U+200B です。
サードパーティのソースコードは、読む前に U+202A 〜 U+202E をスキャンしてください。これらは Trojan Source の背後にある bidi オーバーライドです。
ディテクタの仕組み
ディテクタは JavaScript としてブラウザ内で完全に動作します。テキストはデバイスから一切外に出ません。これは、機密性の高い識別子やソースコードを貼り付ける場合に重要です。Chrome、Firefox、Safari、Edge、およびデスクトップ・モバイルのモダンブラウザすべてで動作します。スキャン対象は、U+200B 〜 U+200F 範囲のゼロ幅文字、U+202A 〜 U+202E と U+2066 〜 U+2069 の双方向オーバーライド、word joiner の U+2060、ソフトハイフンの U+00AD、そしてファイル先頭以外の位置に現れた U+FEFF(バイトオーダーマーク)です。このツールはコードポイント単位で不可視文字をフラグ立てし、ホモグリフ(他の文字に見える可視文字)は検出しない点に注意してください。
