Back

Web向けメールアドレス難読化テクニック

Web向けメールアドレス難読化テクニック

公開されているメールアドレスはすべて標的になります。HTMLに素の mailto: リンクを置いた瞬間から、自動収集ツールはそれを素早く拾い集められます。本記事では、フロントエンド開発者が実用的に使えるメールアドレス難読化テクニックを取り上げ、それぞれが何をするものか、現代のスクレイピングツールに対してどの程度有効か、そしてユーザビリティやアクセシビリティの面でどこに弱点があるかを解説します。

最初に重要な注意点を一つ。メールアドレスの難読化はセキュリティ上の保証にはなりません。減らせるのは自動収集であって、標的型の収集ではありません。ヘッドレスブラウザ、AI支援型スクレイパー、OCRツールの登場により、いくつかの古いテクニックはかつてほど信頼できるものではなくなっています。目的は収集を不可能にすることではなく、収集のコストを引き上げることです。

キーポイント

  • 素の mailto: リンクは簡単にスクレイピングされ、href 属性と表示されるDOMの両方でアドレスが露出します。
  • HTMLエンティティエンコーディングは、単純な正規表現ベースの収集ツールに対して驚くほど有効ですが、ヘッドレスブラウザに対してはまったく防御になりません。
  • JavaScriptベースのテクニック(文字列連結、変換関数、SubtleCrypto を使ったAES暗号化)は、基本的なスクレイパーに対するハードルを大きく引き上げます。
  • 反転テキストや ::after 疑似要素のようなCSSトリックはユーザビリティとアクセシビリティを損なうため、避けるべきです。
  • コンタクトフォームはページHTMLにアドレスを露出させずに済みますが、ハニーポットフィールドや、Cloudflare Turnstileのようなプライバシーを尊重するCAPTCHAと組み合わせるべきです。
  • 複数のテクニックを重ねることで、現実的に最も広い範囲をカバーできます。

素のmailtoリンクが問題になる理由

このような無防備なmailto: リンク:

<a href="mailto:contact@example.com">Email us</a>

は簡単にスクレイピングされます。正規表現ベースのボットは即座に見つけてしまいます。アドレスは2箇所で露出します。href 属性と、リンクテキストとしてアドレスを表示する場合は可視のDOMにも現れます。スパムを意味のあるレベルで減らしたいなら、両方を保護する必要があります。

HTMLエンティティエンコーディング

メールアドレスの各文字をHTMLエンティティで置き換えるのは、最も古い難読化テクニックの一つです:

<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#99;&#111;&#110;&#116;&#97;&#99;&#116;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;">Email us</a>

ブラウザはこれを正しくデコードして、機能するmailtoリンクとしてレンダリングします。Spencer Mortensenによるハニーポットテストによると、これはクリック可能なリンクを狙う収集ツールを高い割合でブロックしました。サーバーサイドのライブラリで簡単にエンティティをデコードできることを考えると、驚くほど有効です。これが機能するのは、多くのスクレイパーが洗練されていないからです。とはいえ、ヘッドレスブラウザや、生のHTMLではなくレンダリング済みのDOMを処理するスクレイパーに対する防御にはなりません。

ユーザビリティ: 影響なし。 アクセシビリティ: 完全に互換。 保守性: 手書きでは煩雑なので、ジェネレーターを使いましょう。

JavaScriptベースの難読化

JavaScriptを使ったテクニックは、メールアドレスを静的なHTMLから完全に切り離すため、基本的なスクレイパーに対するハードルを大きく引き上げます。

文字列連結 はアドレスを複数の文字列フラグメントに分割し、実行時に組み立てます。完全なアドレスはHTMLソースには現れず、実行後にメモリ上にのみ存在します。

<a id="contact-link" href="#">Email us</a>
<script>
  const user = "contact";
  const domain = "example.com";
  const link = document.getElementById("contact-link");
  link.href = "mailto:" + user + "@" + domain;
  link.textContent = user + "@" + domain;
</script>

カスタム変換関数 はさらに踏み込みます。HTMLソースには意味のないプレースホルダーテキストが含まれ、小さなJS関数が、ページが実際のブラウザ環境でレンダリングされたときにのみ、それを有効なアドレスに変換します。これはアドレスを復元するために完全なJavaScript実行が必要となるため、mailtoリンクのスパム対策として最も効果的なアプローチの一つです。

AES暗号化 はブラウザのネイティブ SubtleCrypto APIを使い、ビルド時にアドレスを暗号化し、クライアント側で復号します。SubtleCrypto はセキュアコンテキストでのみ動作するため、HTTPSが必要です。これは既に使っているはずです。ブラウザサポートは Can I Use によると、現代の主要ブラウザで広く利用可能です。

重要な制限: これらのテクニックはいずれも、JavaScriptを完全に実行するPuppeteerやPlaywrightのようなヘッドレスブラウザを止めることはできません。ただし、依然として正規表現ベースで生のHTMLにのみ作用する大多数のスクレイパーは止められます。

ユーザビリティ: 正しく実装すれば優秀。 アクセシビリティ: 実装次第。レンダリングされたリンクがキーボードナビゲーション可能で、スクリーンリーダーに対応していることを確認してください。 保守性: 中程度。

避けるべきCSSベースのテクニック

いくつかのCSSアプローチ(テキスト方向の反転、画面外への配置、::after 疑似要素など)は一見賢そうに見えますが、ユーザビリティを著しく損ないます。::after でレンダリングされたテキストは選択もコピーもできません。反転テキストは、ユーザーがコピーできたとしても混乱させます。これらのテクニックは、HTMLと一緒にCSSを解析するスクレイパーに対しても無力です。避けてください。

代替手段としてのコンタクトフォーム

公開メールアドレスをコンタクトフォームに置き換えれば、ページHTMLにアドレスを露出させることを完全に避けられます。トレードオフはユーザビリティです。多くのユーザーは直接メールを好み、長いフォームはコンバージョンを下げます。

コンタクトフォームを使うなら、保護しましょう。ボットは自動的にフォームを送信できます。ハニーポットフィールド(実際のユーザーは記入しないがボットは通常記入する隠し入力)を、軽量でアクセシブルな第一防御層として追加してください。トラフィックの多いフォームには、Cloudflare Turnstile がプライバシーを尊重するCAPTCHAの代替として、reCAPTCHA v2よりも摩擦の少ない選択肢を提供しています。

アクセシビリティに関する注意: 画像ベースのCAPTCHAは視覚障害のあるユーザーに実質的な障壁を作ります。必ず音声による代替手段を提供するか、視覚的なチャレンジのみに依存しないCAPTCHAソリューションを選んでください。WCAG 2.2のガイダンス が良い参考になります。

Cloudflareのメールアドレス難読化

サイトが Cloudflare の背後で稼働しているなら、組み込みの Email Address Obfuscation を有効にする価値があります。Cloudflareはページがクライアントに到達する前に、エッジでHTML内のメールアドレスを書き換え、ブラウザでそれらを復元する小さな遅延デコードスクリプト(email-decode.min.js)を注入します。スクリプトは defer で読み込まれるため、レンダリングをブロックしません。

このアプローチは事実上ユーザーには透過的で、コードベースへの変更は不要です。主な制限は、<script><noscript><textarea><head> タグ内には適用されないこと、そして Cache-Control: no-transform ヘッダー付きでページを配信している場合は機能しないことです。

カバレッジを高めるためのテクニックの重ね合わせ

単独で十分なテクニックは存在しません。多くのサイトにとって実用的な組み合わせは:

  • mailtoリンクの href 属性を保護するために JavaScript変換またはAES暗号化 を使う。
  • 表示されるアドレステキストには二次層として HTMLエンティティエンコーディング を適用する。
  • 代替の連絡経路として ハニーポットフィールド付きのコンタクトフォーム を追加する。
  • 既にCloudflareのネットワーク上にあるなら、Cloudflare Email Obfuscation を有効にする。

この層状のアプローチは、リンク属性と可視テキストの両方をカバーし、生のHTMLしか読まないスクレイパーとJavaScriptを実行するスクレイパーの間のギャップを処理します。

まとめ

メールアドレスの難読化は、自動収集を意味のある形で減らします。ハニーポットのデータは、多くの収集ツールが依然として洗練されていないため、基本的なテクニックでさえ大量のスクレイパーをブロックできることを一貫して示しています。しかし、難読化は優れたスパムフィルターの代替にはなりませんし、決意のある標的型の収集を止めることもできません。

しっかりしたテクニックを1つか2つ実装し、意味のあるところで重ね合わせ、次に進みましょう。節約した時間は、他のことに使うほうが有効です。

FAQ

はい、ただし洗練されていないスクレイパーに対してのみです。ハニーポットテストでは、多くの正規表現ベースの収集ツールがエンティティをデコードせずに生のHTMLを読むため、依然として多くをブロックしていることが示されています。しかし、Puppeteerのようなヘッドレスブラウザを含む、レンダリング済みDOMを解析するスクレイパーはデコードされたアドレスを見ることができます。単独の防御策ではなく、より広い戦略の一層として使ってください。

はい。PuppeteerやPlaywrightのようなヘッドレスブラウザはJavaScriptを完全に実行するため、文字列連結、変換関数、AES復号を含む実行時デコードに依存するあらゆるテクニックは回避されてしまいます。JSベースの難読化の価値は、依然として自動収集トラフィックの多くを占める、より大きな母集団である正規表現ベースのスクレイパーを止める点にあります。

目的次第です。コンタクトフォームはページHTMLにメールアドレスを露出させることを避けられるため、基本的な収集に対してより強い保護を提供します。しかしフォームはコンバージョンを下げ、多くのユーザーは直接メールを好みます。バランスの取れたアプローチは両方を提供することです。望むユーザーには難読化されたmailtoを、フォールバックとしてハニーポットフィールド付きの保護されたコンタクトフォームを用意しましょう。

通常は意味のある形での影響はありませんが、それでも実際のページや支援技術でテストすべきです。デコードスクリプトはページが読み込まれた後にクライアント側でアドレスを復元し、その後はキーボードナビゲーションは通常通り機能します。検索エンジンは通常メールアドレスをランキングシグナルとして扱わないため、SEOへの実質的な影響はほとんどありません。ただし、ページが Cache-Control no-transform ヘッダーで配信されていないことを確認してください。

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay