1,418文字の視覚的欺瞞:Unicode混同攻撃の実態とSSIMで見える「本当に危険な82文字ペア」

未分類
Picsum ID: 89

1,418文字の視覚的欺瞞:Unicode混同攻撃の実態とSSIMで見える「本当に危険な82文字ペア」

title: "1,418文字の視覚的欺瞞:Unicode混同攻撃の実態とSSIMで見える「本当に危険な82文字ペア」"
date: 2026-02-26
category: Security
tags: unicode, security, homoglyph, ssim, visual-attack


はじめに:見えない脅威

Web開発者は皆、「SQLインジェクション」や「XSS」といった攻撃には馴染みがあるだろう。だが、「視覚的な類似性」を悪用する攻撃についてはどうだろうか?

例えば、この2つのドメインを見分けられるだろうか?

  • gοοgle.com(ギリシャ文字ο)
  • google.com(ラテン文字o)

一見して同じに見える。だが、前者はフィッシングサイトかもしれない。このような攻撃は「Homoglyph Attack(同形文字攻撃)」と呼ばれ、Unicodeの膨大な文字セットが温床となっている。

2026年2月、開発者Paul Tendoが1,418組のUnicode混同文字ペアを230種類のフォントで実際にレンダリングし、**SSIM(Structural Similarity Index Measure)**を使って定量化する実験を行った。その結果は衝撃的だった。

96.5%の混同文字ペアは実際には危険ではない。
だが、82ペアは「ピクセルレベルで完全に同一」だった。

本記事では、この実験の詳細と、Web開発者が知るべき実践的対策を解説する。


What:Unicode混同文字攻撃とは

Unicode Consortiumは、世界中の文字体系を統一的に扱うための標準を策定している。現在、Unicodeには15万文字以上が含まれている。

その中には、視覚的にほぼ同じに見えるのに、異なるコードポイントを持つ文字が多数存在する。これらは「Confusables(混同文字)」としてUTS #39で文書化されている。

主な混同文字の例

正規文字混同文字スクリプト
aаキリル文字pаypal.com
eеキリル文字еmail.com
oοギリシャ文字gοοgle.com
0Оキリル文字О0
lӏキリル文字ӏogin

これらを悪用した攻撃パターン:

  1. フィッシングドメイン: 類似ドメインで偽サイトをホスト
  2. IDなりすまし: SNSで類似ユーザー名を取得
  3. コード難読化: 変数名に混同文字を使用して可読性を低下

How:実験手法

confusable-visionツール

Paul Tendoは、この問題を定量化するためにconfusable-visionというツールを開発した。

処理フロー:

1,418混同文字ペア
    ↓
fontconfigで文字対応フォントを検索
    ↓
8,881回のターゲットレンダリング(48×48グレースケールPNG)
    ↓
235,625回のSSIM比較
    ↓
スコア付きJSON出力

なぜSSIMなのか

SSIM(Structural Similarity Index Measure)は、2つの画像の類似性を測る指標で、-1から1の値を返す:

  • 1.0: ピクセル完全同一
  • 0: 構造的相関なし
  • -1: 反相関(ランダムノイズより似ていない)

学習ベースのCNN(VGG16など)ではなくSSIMを採用した理由は明確だ:再現性。GPUも学習データもモデル重みも不要。誰でも同じ結果を再現できる。

フォント発見

230種類のシステムフォントを使用:

カテゴリ用途
standard74Latin主要フォント(Arial, Menlo, Georgia等)
script49CJK、Indic、Thai等のラテン文字含有フォント
noto103非ラテンスクリプト用Noto Sans
math3STIX Two Math等
symbol1Apple Symbols

Results:衝撃の統計

ヘッドライン:96.5%は危険ではない

バンド%説明
High (>= 0.7)493.5%本当に危険
Medium (0.3-0.7)68148.0%フォント依存
Low (< 0.3)61143.1%視覚的に混同不可
No data775.4%システムフォントに存在せず

中央値SSIM: 0.322 — 典型的な混同文字は、実際にはあまり似ていない。

だが82ペアはピクセル完全同一

平均SSIMは脅威を過小評価する。攻撃者は「少なくとも1つのフォント」で成功すればよい。

例:キリル文字ԁ (U+0501) とラテン文字d

  • 平均SSIM: 0.781(中程度)
  • しかし8つのフォントでSSIM 1.000(ピクセル完全同一)

Arial, Menlo, Cochin, Tahoma, Charter, Georgia, Baskerville, Verdana — これら全てで完全に区別不可能。

最も危険なスクリプト

キリル文字ホモグリフ:真の脅威

キリル文字はラテン文字と多くの共通グリフを持つ。一部は同一のグリフを共有:

  • а → a
  • е → e
  • о → o
  • р → p
  • с → c
  • х → x

これらは履歴的に同一のグリフから派生したため、多くのフォントで完全に区別不可能。

ローマ数字:意図的なグリフ再利用

ローマ数字(Ⅰ, Ⅱ, Ⅲ等)は多くのフォントでラテン文字Iと同じグリフを使用。これはバグではなく、設計上の決定

ヘブライ語Paseq:予期せぬ発見

ヘブライ語のPaseq(U+05C0)は、一部のフォントでラテン文字の縦棒(|)と完全に同一にレンダリングされる。これは予期せぬ発見だった。


最も危険なフォント

高危険率フォント

フォントによって危険度が大きく異なる。一部のフォントは混同文字ペアの20%以上をピクセル同一でレンダリングする。

低危険率フォント

逆に、一部のフォントは混攻撃に対して非常に堅牢。独自のタイポグラフィックデザインが、異なるスクリプト間の視覚的差異を保持している。


Web開発者への実践的対策

1. IDN(国際化ドメイン名)の検証

// Punycode形式に変換して確認
function checkDomain(domain) {
  const punycoded = punycode.toASCII(domain);
  if (punycoded !== domain) {
    console.warn('非ASCII文字が含まれています:', punycoded);
  }
}

checkDomain('gοοgle.com'); // xn--ggle-6qda.com

2. ユーザー名の正規化

// UTS #39準拠の正規化
const { confusables } = require('unicode-confusables');

function normalizeUsername(username) {
  return username.normalize('NFKC')
    .split('')
    .map(char => confusables.get(char) || char)
    .join('');
}

normalizeUsername('pаypal'); // 'paypal'(キリルа → ラテンa)

3. 視覚的警告の実装

// 混在スクリプト検出
function detectMixedScript(text) {
  const scripts = new Set();
  for (const char of text) {
    const script = getScript(char); // Unicodeスクリプト判定
    scripts.add(script);
  }
  
  if (scripts.size > 1) {
    return {
      warning: '複数の文字体系が混在しています',
      scripts: Array.from(scripts)
    };
  }
  return { safe: true };
}

4. フォント選択の考慮

危険率の低いフォントを優先的に使用。特に、ユーザー生成コンテンツを表示する領域では、フォント選択がセキュリティ上の決定となり得る。


Why:なぜこの問題は解決されないのか

互換性 vs セキュリティ

Unicodeの歴史的互換性要件により、多くの「同一グリフ・異なるコードポイント」が標準化されている。これを変更すると、膨大な既存データが破損する。

TR39の限界

UTS #39のconfusables.txtは視覚的類似性を主張しているが、大規模な実証検証は行われてこなかった。多くのエントリはNFKC正規化下での意味的マッピングに基づいており、実際のレンダリング結果とは乖離がある。

フォント依存性

同一の文字でも、フォントによって全く異なるグリフでレンダリングされる。Webアプリケーションはエンドユーザーのフォントを制御できないため、完全な対策は困難。


When:攻撃が成功する状況

  1. ドメイン登録時: 視覚的に類似したドメインを取得
  2. アカウント作成時: 正規ユーザー名の混同版を登録
  3. コードレビュー時: 変数名の微妙な違いを見逃す
  4. URL表示時: アドレスバーのドメインを目視確認

Where:影響範囲

  • Webブラウザ: ドメイン、URLパラメータ、フォーム入力
  • SNS: ユーザー名、ハッシュタグ、メンション
  • メッセージングアプリ: 送信者名、グループ名
  • コードエディタ: 変数名、関数名、識別子
  • 決済システム: 口座名義、送金先

Conclusion:見えない脅威への対策

Paul Tendoの実験は、Unicode混攻撃の実態を初めて大規模に定量化した。重要な知見:

  1. 96.5%の混同文字は実際には危険ではない — 過剰な心配は不要
  2. だが82ペアは本当の脅威 — 特にキリル文字ホモグリフ
  3. フォント選択がセキュリティに影響 — UIデザインの新たな責任
  4. SSIMによる定量的評価が可能 — 主観から客観へ

推奨アクション

  1. IDN/Punycode検証を導入
  2. UTS #39準拠の正規化パイプライン構築
  3. 複数スクリプト混在の警告UI実装
  4. 定期的な混同文字データベース更新

視覚的欺瞞は「見えない」攻撃だが、適切な対策で可視化し、無力化できる。開発者は今こそ、Unicodeの深淵を理解し、ユーザーを守る準備をすべきだ。


参考リンク


この記事はReddit r/programmingで話題の投稿を基に、技術的背景と実践的対策を深掘りして執筆しました。


📚 関連記事


📚 AI学習におすすめの資料

ChatGPTやAIを学ぶなら、以下の資料がおすすめです:

Amazonアフィリエイトリンクを使用しています

🛒 おすすめGPU商品(Amazon)

NVIDIA GeForce RTX 4090

価格: 200,000-250,000円

特徴: ハイエンドGPU、AI開発・ゲーミング向け

Amazonで見る


NVIDIA GeForce RTX 4080 SUPER

価格: 150,000-180,000円

特徴: 高性能GPU、コスパ重視

Amazonで見る


NVIDIA GeForce RTX 4070 Ti SUPER

価格: 100,000-130,000円

特徴: ミドルハイエンド、バランス良い

Amazonで見る


コメント

タイトルとURLをコピーしました