Flatt Security Blog

株式会社Flatt Securityの公式ブログです。プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

株式会社Flatt Securityの公式ブログです。
プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

Black Hat USA 2019: 今注目すべき Web セキュリティ関連トピックの解説

はじめに

BlackHat USA 2019

株式会社 Flatt Security でセキュリティエンジニアをしている米内(@lmt_swallow)です。私は 2019/8/3 から 2019/8/8 で開催された Black Hat USA 2019 と、続いて開催された DEFCON 27 に参加してきました。本記事では、特に Black Hat USA 2019 で印象的だった以下の 4 つの発表について、簡単な紹介と解説をしたいと思います。

以下は技術的な (あるいは倫理的な) 誤りがないように細心の注意を払って記述しましたが、誤りを含む可能性もあります。またこの記事は技巧的な部分に極力触れず、攻撃の原理や問題が生じる原因にフォーカスして書かれています。もし本稿を通してより詳細が知りたくなったという方や、記述に幾ばくかの違和感を感じた方がいらっしゃいましたら、ぜひオリジナルの文献をご参照ください。

HTTP Desync Attacks: Smashing into the Cell Next Door

モダンな Web アプリケーションはしばしば CDN やリバースプロキシとその背後にある実際の Web アプリケーション、というような多段構成をとります。以降は James Kettle 氏の Whitepaper 等の表記にあわせるため、「フロントエンド」「バックエンド」という言葉を次のような意味で用いることにします。

  • 「フロントエンド」 … CDN やリバースプロキシのような、ユーザーからのリクエストをはじめに受け取るサーバ。
  • 「バックエンド」 … フロントエンドの背後にある Web アプリケーション本体。

James Kettle 氏 のこの発表は、HTTP Desync Attacks と呼ばれる新たなクラスの攻撃を提案するものでした。この攻撃のターゲットは、以下のような条件が成立しているような Web アプリケーションです。

  • ユーザと Web アプリケーションの間にリバースプロキシなどの中継 ―― 資料ではこれをフロントエンドと表現している ―― が存在する
  • そのフロントエンドとバックエンドの通信が 1 本のコネクションにより行われている(e.g. HTTP/1.1 の Keep-Alive)
  • フロントエンドとバックエンドの間で、Transfer-Encoding ヘッダと Content-Length ヘッダが同時に存在しているようなリクエストへの対応が異なる

このような Web アプリケーションに対しては、Transfer-Encoding ヘッダと Content-Length ヘッダの両方を含むようなリクエストを送信することで、フロントエンドとバックエンドの間で「そのリクエストの終端がどこか」の認識違いを引き起こす(Desynchronize する)ことができます。このことは後に詳しく説明します。

この攻撃により、攻撃用のリクエストの後続のリクエストの先頭部分に任意の文字列を付加することができます。攻撃者はこの挙動を利用して、バックエンドに対して通常は送信され得ない HTTP リクエストを送信したり、他ユーザーに対して通常とは異なるレスポンスを返させたりすることができます。とりわけ XSS や Cache Poisoning などにも転用可能です。

Request Smuggling

Request Smuggling とはあるユーザーから発行された HTTP リクエストに干渉する手法のことです。これは Watchfire が 2005 年に提案した攻撃手法1で、この提案時には複数の Content-Length ヘッダを含むリクエストに対するフロントエンドとバックエンドの挙動の違いが利用されていました。今日においてはこのような攻撃の成立は珍しいですが、こちらの挙動は非常にわかりやすいので、まずこの古い方法について説明したいと思います。

例えば以下のようなリクエストを攻撃者がフロントエンドに対して発行したとします。これをリクエスト 1 と呼ぶことにします。

POST / HTTP/1.1
Host: example.com
Content-Length: 5
Content-Length: 4

12345

またこのリクエストに引き続き、以下のようなリクエストが発行されたとします。これをリクエスト 2 と呼ぶことにします。

GET /js/script.js HTTP/1.1
Host: example.com

このとき、もし 1 つ目のリクエストの処理の際にフロントエンドが 1 つ目の Content-Length (値は 5) を採用するならば、バックエンドには以下のようなデータが送信されます。

POST / HTTP/1.1
Host: example.com
Content-Length: 5
Content-Length: 4

12345GET /js/script.js HTTP/1.1
Host: example.com

もしここでバックエンドも 1 つ目の Content-Length (値は 5) を用いてデータを処理するのであれば、なんの問題も起こりません。しかしバックエンドが 2 つ目の Content-Length (値は 4) を採用してしまった場合、バックエンドからは、次のような 2 つのリクエストが送信されてきたように見えてしまいます。これらをリクエスト1+, リクエスト2+ と呼ぶことにしましょう。

POST / HTTP/1.1
Host: example.com
Content-Length: 5
Content-Length: 4

1234
5GET /js/script.js HTTP/1.1
Host: example.com

このようにして攻撃者は、後続のリクエストの先頭に 5 を追加することができます。これらのリクエストがバックエンドにより順に処理された結果をレスポンス1+, レスポンス2+ とすると、フロントエンドはレスポンス 1+, 2+ をそれぞれリクエスト 1, 2 に対するものだと解釈します。ここで実際のレスポンス 2+ はリクエスト 2+ (5GET /js/script.js HTTP/1.1 ...) によるものでした。こうして攻撃者は正規の後続のリクエストの先頭に文字列を付加し、そのようにして作られたリクエストの結果を後続のリクエストへのレスポンスとすることができます。

もちろん追加する文字列として 5 ではなく、GET /path HTTP/1.1 ... のような HTTP ヘッダを採用することも出来るわけですから、攻撃者はバックエンドに対して、任意の HTTP ヘッダを持ったリクエストを発行することができます。こうしてバックエンドに対して予期されないリクエストを与えたり、後続のリクエストに対するレスポンスを全く異なるものにしたりできるわけです。

しかしこのような Content-Length ヘッダを 2 つ用いるような方法は、現代のほとんどのソフトウェアにおいて動作しません。しかし今回 James Kettle 氏は次に示すリクエストのような、Content-Length ヘッダと Transfer-Encoding ヘッダが共存している場合に着目しました。

POST / HTTP/1.1
Host: example.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

このリクエストの処理の際に、もしフロントエンドとバックエンドが利用するヘッダが異なるのなら (e.g. フロントエンドは Content-Length ヘッダを利用するが、バックエンドは Trasnfer-Encoding を利用する)、ここまで示したような問題が起こることが容易に想像できますね。ただもちろんこのような問題を避けるため、RFC2616 には以下のような記述があります。

If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.

しかし実際には全ての実装がこれに従っているわけではないですし、リクエストヘッダのパースの挙動差(e.g. あるソフトウェアでは Transfer-Encoding: zchunkedTransfer-Encoding ヘッダとして認識されるが、あるソフトウェアではそうは認識されない) も存在しています。

したがってこのような挙動差や実装不備を利用することによって、Content-Length ヘッダと Transfer-Encoding ヘッダを利用して Request Smuggling を行うことができる場合があるのです。

なお James Kettle 氏の Whitepaper にもある通り、このような挙動差の検証に関しては、regilero 氏のリサーチ が参考になります。

Desyncronization とそれによる攻撃

このような Request Smuggling と呼ばれる手法を利用して、攻撃者は「フロントエンドサーバが処理する HTTP リクエストの並び」と「バックエンドサーバが処理する HTTP リクエストの並び」を異なったものにすることができます。このような行為を James Kettle 氏は Desynchornize と呼んでいます。

ややこれは抽象的な言い方ですが、例えば Request Smuggling の項で示した例においては、フロントエンドとバックエンドは次のように Desynchronize されています。 - フロントエンドが処理しているリクエストの並び … リクエスト 1, 2 - バックエンドが処理しているリクエストの並び … リクエスト 1+, 2+

ところでこの Desynchronize を行うことによって、攻撃者は、次のようなことができます。

  • バックエンドに対して予期されていないリクエストを与える (e.g. ありえないリクエストヘッダの付与等)
  • 攻撃用のリクエストの直後の続くリクエストの結果を、HTTP ヘッダの追加によりコントロールする

さらにこれらのような攻撃の他にも、James Kettle 氏はこの Desynchronize を利用して、次のような攻撃を実現しています。

  • 反射 XSS を利用した他リクエストへのスクリプトの差し込み … 反射 XSS のあるエンドポイントに対する リクエストを行うようなヘッダを後続リクエストに追加することで、そのレスポンスに JS を挿入する。
  • Cache Deception / Cache Poisoning … フロントエンド側でキャッシュされるような後続リクエストに対して、セッションに紐付いた情報を GET するようなヘッダを追加する。

どちらもやや非直感的ですから、ここから簡単に説明を加えたいと思います。

まず「反射 XSS の他リクエストへの差し込み」について考えてみましょう。例えば http://vulnerable.example.com// には XSS 脆弱性がなく、/xss.php には GET パラメータの q に XSS 脆弱性があるとします。また攻撃者のリクエストの直後に、/ (XSS の無いページ) への次のようなリクエストが他ユーザーから発行されるとします。これをリクエスト A と呼ぶことにします。

GET / HTTP/1.1
Host: vulnerable.example.com
Cookie: hoge=fuga
以下省略

いま攻撃者が Request Smuggling により、このリクエストの先頭に GET /xss.php?q=3Cscript%3Ealert(1)%3C%2Fscript%3E HTTP/1.1[CRLF]Foo: を追加したとします。このときバックエンドはリクエスト A の代わりに、次に示すリクエスト A+ を処理します。

GET /xss.php?q=3Cscript%3Ealert(1)%3C%2Fscript%3E HTTP/1.1
Foo: GET / HTTP/1.1
Host: vulnerable.example.com
Cookie: hoge=fuga
以下省略

このリクエストは XSS のあるページ /xss.php へのリクエストであり、このリクエストに対するレスポンスには <script>alert(1)</script> が含まれることでしょう。しかしこのレスポンスは、フロントエンドから見ればリクエスト A(すなわち他ユーザーが / に対して発行した GET リクエスト)に対するものです。結果攻撃者は反射型 XSS を利用することで、他ユーザの XSS 脆弱性のないページへの GET リクエストに対するレスポンスとして、任意 JS を挿入することができることになります。つまり Desynchronize と XSS を組み合わせることで、ユーザー操作の誘導を行うことなく XSS を実現することができてしまうのです。

Desynchronize による Cache Poisoning / Cache Deception の手法についても、この XSS の差し込みと同じような原理で説明できます。例えば攻撃者のリクエストの直後に、フロントエンド側でキャッシュされるようなファイル (e.g. CSS, JS, その他静的なコンテンツ) への GET リクエストが他ユーザーから送信されたとします。このときに攻撃者は上述の XSS の差し込みのような手法を用いて、そのリクエストに対するレスポンスとして悪意のあるコンテンツを設定し、キャッシュさせることができます (Cache Poisoning)。あるいはリクエストの先頭に GET /sensitive_data HTTP/1.1[CRLF]Foo: ... のようなヘッダを付加することにより、ユーザーのセッションに紐付いた情報をキャッシュさせることができます(Cache Deception)。

本稿は Whitepaper やスライドで触れられた事例については触れませんが、このような攻撃は非常にインパクトのあるものだと筆者は感じています。James Kettle 氏が Whitepaper の結論部分で "This topic is still under-researched, ..." と述べているように、この攻撃に関連する事例は今後も登場していくのではないでしょうか。

対策

James Kettle 氏はこのような攻撃に対する対策手法として、フロントエンドとバックエンドの間の通信に HTTP/2 を利用することや、フロントエンド側でリクエストの適切な正規化を行うことを勧めています。

また開発時に意識するのはもちろん、実際に攻撃が可能かどうかのテストを行うことも重要です。James Kettle 氏は、この HTTP Desync Attacks が可能かどうかを検証するためのツール HTTP Request Smuggler を PortSwigger として公開しています。またこの検査手法は Burp Suite の Scanner にも取り入れられているようです。

興味のある方は、同じく PortSwigger 社から提供されている HTTP request smuggling の学習・演習用ページでこれを試してみると良いでしょう。

ただこの類の攻撃の検証を行う際には、使用するツールやテスト環境による制限に留意しなくてはならない、と James Kettle 氏は述べています。例えば本番環境と全く異なる構成 (e.g. ロードバランサの有無が異なる等) でテストを行うと、本番環境とは異なる結果に終わってしまう場合があります。使用しているツールによりヘッダの値が正規化されてしまう場合 (e.g. Burp Suite のデフォルト設定では、自動的に Content-Length ヘッダの値が調整される) もあるでしょう。確かにこれらに留意しないと、誤ったテスト結果を得てしまう可能性がありますね。

脆弱性診断の際にはテスト用の環境を用いることもしばしばあると思いますが、このようなインフラ面が絡んでくる問題に関しては、検出の不備が起こりえます。今後はできるだけ本番に近い構成での診断の実施が求められていくのかもしれません。

BlackHat USA 2019 の Briefings 会場。暗めの照明のおかげか、それらしい雰囲気に満ちあふれています。

API-Induced SSRF: How Apple Pay Scattered Vulnerabilities Across the Web

Joshua Maddux 氏のこの発表は、API の設計が起因で引き起こされた、それを利用する Web アプリケーションにおける SSRF 脆弱性をテーマにしたものでした。この 2019 年において SSRF の話はやや陳腐にも感じられますが、この発表の切り口は今までのそれとすっかり異なるものです。

Joshua 氏は初めに Schneier 氏の述べた Class Breaks という概念2、すなわち Heartbleed のように多くのシステムの脆弱性を引き起こすような一つの脆弱なコード(あるいは脆弱性そのもの)について着目した後、ではそのような脆弱性を引き起こしている大本の原因は何だろうか、という疑問を提示しました。そこで彼が提示した答えが、Inductive Weakness という概念です。Inductive Weakness とは、それを利用したソフトウェアを書く人間の多くに、似たような脆弱なコードを書かせるような設計のことを指します。

しかし現時点でこの定義はいささか抽象的です。そこで彼はこの後、2 つの例を通して、Inductive Weakness というコンセプトを説明しました。より具体的に述べると、彼は 1 つ目の例として Apple Pay JS API の利用サービスにおける SSRF の例を、2 つ目の例として Webhooks 機能をもつ Web アプリケーションの例を挙げています。

本稿においてもこの 2 つの事例を通して、この Inductive Weakness というものを説明したいと思います。

Apple Pay の例

Apple Pay JS API の Merchant Validation という処理は、次のようなフローを含んでいます。

  1. Merchant Validation に必要な URL をクライアント側で生成し、サーバーに送信する
  2. サーバーは受け取った URL にリクエストし、結果をクライアントに転送する

つまり Apple Pay JS API を利用するために開発者が設置するサーバは、受け取った URL にリクエストをし、その結果をクライアントに返す、という機能を持たなくてはならないということです。このような機能はしばしば SSRF 脆弱性を引き起こします。そして実際に Joshua 氏は Apple Pay JS API を利用している 2 つのデモにおける SSRF 脆弱性を発見しています。

このように、Apple Pay の設計は、それを利用する開発者に脆弱なコードを書かせてしまいやすいものでした。これを言い換えると、Apple Pay JS API の設計は Inductive Weakness を持っていたということです。

Joshua 氏はこのような Inductive Weakness の発見を受けて、ホワイトリストベースの通信制限や、各種クラウドプロバイダが提供しているメタデータをしっかり保護しておくことを推奨しています。

Webhooks 機能の例

Webhooks 機能は近年多くの Web サービスが有している機能です。しかし Webhooks 機能は Web アプリケーションのあるサーバから任意 URL に対してリクエストを送信できる機能ですから、しばしばその Web アプリケーションの SSRF 脆弱性を引き起こします。実際に DropboxSlack など、多くの Web アプリケーションに対してこのような SSRF 脆弱性の存在が報告されてきました。

一方 Joshua 氏が目をつけたのは、このような Web アプリケーションの有しうる SSRF 脆弱性ではなく、それを受け取る側の脆弱性でした。実際に Joshua 氏は Twilio の Webhooks を利用する Web アプリケーションらが、その Webhook リクエストの出自をチェックしているかどうか (i.e. 署名の検証をしているか) の調査を行い、結果として多くの OSS が検証を行っていないという結果を得ています。

Webhook リクエストの出自が検証されない場合、Webhook を受け取るエンドポイントを知っている攻撃者は、容易にそのエンドポイントを攻撃する事ができます。例えば Gitlab のように URL が含まれる Webhook に関しては、それを受け取るサーバが「そのリポジトリを clone したり、その URL に対して HTTP アクセスを行うかも」といった推測を行い、SSRF 攻撃を試すことなどができるでしょう。

このように、Webhooks 機能も設計次第では Inductive Weakness を持つと言えます。Joshua 氏はこの対策として、Webhooks 機能により送信されるリクエストの中身をリソースにアクセスするためのトークンに置き換えることや、署名の検証を行っていない Webhook 受信者に対して警告を出すことなどを提案しています。

Inductive Weakness を生み出さないために

Joshua 氏はこの講演の締めとして、このような Inductive Weakness を生み出さないためにも、以下の 3 つに気をつけるべきであると述べています。

  1. 例示用のコードをセキュアにすること。
  2. URL を受け渡す処理に注意すること。
  3. ドキュメントに「こうやって使わないと脆弱になっちゃうよ!」と注意書きを書かないと行けないようなときには、そのような注意書きがなくてもいいようにできないか考えなおすこと。

このような設計段階で生じてしまう問題については、開発早期での発見が必要不可欠です。そのためには開発者チームとセキュリティチームの適切な連携が必要だと言えるでしょう。またこの主の問題を未然に防ぐためには、BlackHat USA 2019 の Keynote でも語られたように、チーム体制のシフトが強く求められているのだと筆者は感じます。

Denial of Service with a Fistful of Packets: Exploiting Algorithmic Complexity Vulnerabilities

Nathan Hauke 氏と David Renardy 氏はこの発表で、3 つの彼らが見つけた Algorithmic Complexity 脆弱性についての解説と、そのような脆弱性の自動探索の手法の紹介をしました。

Algorithmic Complexity (AC) 脆弱性とは名前の通り、アプリケーションが使用しているアルゴリズムの最悪計算量が著しく悪く、かつそのアルゴリズムに最悪計算量を与える入力を渡すことが出来る場合に、攻撃者に DoS 攻撃を実施される場合がある、という脆弱性です。これは CWE (Common Weakness Enumeration; 脆弱性の種類の識別のための共通の基準) においても CWE-407 としてリストアップされているものです。

このような攻撃は少ない通信量(low-bandwitdh)で DoS を引き起こせるという点で攻撃者にとっては有益であり、かつアプリケーション開発者にとっては事前の想定が面倒な点で厄介です。

筆者の調べによると、AC 脆弱性を用いた DoS 攻撃が初めて論文の形で提案されたのは 2003 年ごろの Crosby and Wallach によるもの であるようです。またその他に有名な AC 脆弱性による DoS に関する発表としては、2011 年の CCC 28c3 での発表 や、それを元にした 2012 年の Aumasson 氏の発表 が挙げられます。また発表者らは BlackHat USA 2016 の Decompression Bomb に関する発表 や、DEFCON 23 の ReDOS に関する発表 なども先行研究として挙げています。

しかし発表者らは、このような歴史を経た上でも AC 脆弱性が今に至るまで十分に認識されていないことを訴えました。とりわけ彼らはアプリケーション開発者、設計者、ペネトレーションテスター、セキュリティ研究者の間で、この AC 脆弱性に対する認識にギャップがあると述べています。そしてそれを裏付けるように、発表者らは実際に Dropbox 製品を始めとした3いくつかの製品において AC 脆弱性を発見しています。

筆者自身も常に最悪計算量を考えながら実装しているわけではないので、気をつけなくては、と思った次第です。彼らが公開している「最悪計算量を与える入力を生成してくれるツール」である ACsploit はウォッチしておく価値がありそうです。

初日の Keynote 会場の様子です。会場のかっこよさに感動。

HostSplit: Exploitable Antipatterns in Unicode Normalization

Jonathan Birch 氏のこの発表は、Unicode 正規化の仕組みを URL フィルタバイパスに利用する新たな攻撃手法 HostSplit (とその亜種である HostBond) を提案するものでした。本稿では HostSplit 脆弱性についてのみ紹介します。

IDN / IDNA の基礎知識

講演資料中ではあまり丁寧には触れられていないので、本題に先立って、必要な事前知識の解説から入りたいと思います。

IDN (Internationalized Domain Names; 国際化ドメイン名) には U-label と A-label の 2 つの表現方法があります。U-label とは Unicode 文字を含む画面に表示する際の用いられる形式であり、A-label とは ASCII 文字のみからなる、DNS 等のプロトコルで IDN を利用する際の形式です4。例えば 総務省.jp という IDN の U-label 形式での表現は 総務省.jp であり、この A-label 形式での表現は xn--lhr645fjve.jp となっています。また U-label から A-label に変換する処理は ToASCII 処理、その逆の処理は ToUnicode 処理と呼ばれています5。このような変換を試したい際には、Punycoder などを利用すると良いでしょう。

ところで IDN を標準的に取り扱うための仕様である IDNA には、IDNA2003 と IDNA2008 の 2 つのバージョンが存在しています。これら 2 つの大きな違いは、標準化処理(マッピング処理)が仕様の中で義務付けられているかどうかです。マッピング処理とは U-label で表現されたドメイン名中の大文字を小文字にするような処理であったり、(e.g. AaA.example.com → aaa.example.com)、似たようなグリフを持つコードポイントたち (e.g. è のグリフは U+00E8 としても U+0065 U+0300 としても表せる) をある特定のコードポイントにマップしたりするような処理のことです。

例えば RFC3490 を中心として構成されている IDNA2003 においては、ToASCII 処理の際に Nameprep による文字のマッピングをすることが義務付けられています。RFC3491で定義されている Nameprep とは、RFC3454 で定義されている Stringprep の 1 つのプロファイルです。

一方 RFC5890 を中心に定義されている IDNA2008 においてはそのような過程を義務付けていません6。IDNA2008 は事前にアプリケーションが適切な正規化を行った後に利用されることが想定された仕様となっているわけです。

しかしこれでは IDNA2003 と IDNA2008 の間に大きな挙動差ができてしまいます。そこでそれを補助するために提案されたのが、IDNA2008 向けのマッピング処理を定義する UTS46 です。これは IDNA2008 の仕様の中で Local Mapping あるいは Custom Mapping と呼ばれているマッピングフェーズにおいて利用することの出来るマッピング処理であり、これにより IDNA2003 との互換性をそれなりに保ちながら IDNA2008 を利用することができます。

HostSplit … ToASCII 処理に起因する脆弱性

さて、ここまで説明した通り、以下の 2 つの仕様を利用する場合には ToASCII 処理の過程でマッピング処理が行われます。

  • IDNA2003
  • IDNA2008 と UTS46 を併用

Jonathan 氏はこのマッピング処理に着目し、ここから説明する HostSplit という攻撃を提案しました。まずは次のような文字列について考えてみましょう。

http://evil.c℀.example.com

℀ はコードポイントが U+2100 で表現される文字です。この URL はホスト名として example.com のサブドメインを用いたものであるように見えますね。しかしマッピング処理においては、U+2100 は a/c という 3 つの ASCII 文字に正規化されてしまいます。つまりこの文字列が ToASCII 処理を受けると、以下のような A-label に変換されてしまうのです。

https://evil.ca/c.example.com

結果 ToASCII 処理を受けたことで、この URL はホスト名として evil.ca を用いたものに変わってしまいました。以降この文字列は ToUnicode 処理を受けたとしても evil.ca を用いた URL のままです。

このように、URL のシンタックス上で意味を持つような文字に正規化されてしまうような Unicode 文字を URL 中に用いることによって、ToASCII 処理前後での URL の構造を変化させることができます7。そのため URL を用いたセキュリティチェック (e.g. ホスト名が *.example.com にマッチするか確認する) が Unicode 正規化の前に行われ、チェックを通過した後に ToASCII 処理などで Unicode 正規化などの処理が行われる場合、セキュリティチェックがバイパスされる可能性があります。これが Jonathan 氏の提案した HostSplit 脆弱性です。

IDN を扱う際のベストプラクティス

Jonathan 氏は講演の締めとして、自分のアプリケーションで IDN を扱う際のベストプラクティスについて、次のような点を挙げています。

  • セキュリティチェックの類には、A-label のみを利用する
  • UseSTD3ASCIIRules やそれに類するルールを利用する
  • 標準に従わざるを得ないなどの理由で insecure な 状態にある API を利用する場合には、ラッパー関数を準備する。

実際にユーザーからの入力値として IDN を許容する場合には、十分な注意を払う必要がありますね。

余談: IDN 関連のその他の攻撃

ここからは余談です。IDN に関連したセキュリティ上の問題としては、今回の Jonathan 氏の挙げたようなものの他にも、(IDN) Homograph Attacks を始めとした視覚的な問題(e.g. 2017 年頃の Xudong Zheng 氏のブログポスト)や、文字列比較などの際に起こりうる非視覚的な問題などがよく知られています。視覚的に関しては 2018 年の Elsayed and Shosha の論文が詳しいので8ここでは詳しい解説を行いませんが、IDN に起因する脅威は実在しているようです。

このようなIDN を取り巻くセキュリティ上の問題は Unicode Technical Report #36 に、とりわけ Confusable Strings (似たグリフを持つものの、異なったコードポイント列を持つ 2 つの文字列) の検出に関しては Unicode Technical Standard #39 にまとめられています。また関連した話題として、Cure53 による IDN に関するドキュメント も非常に参考になります。この周辺の問題に興味がある方はぜひ一度読んでみてください。

その他の発表

Web AppSec トラックとしてマークされている講演は、上記の他にも存在しています(リストはこちら)。ここでは触れませんでしたが、WebAuthn 入門のような発表や、Netflix における OSS 脆弱性情報取り扱いの自動化の話などは、特に一見の価値があるかと思います。

今年は「ザ・Web セキュリティ」と呼べるような発表が少なかったものの、どれも興味深いものでした。すでにほとんどの講演のスライドやホワイトペーパーが公開されていますから、ぜひ読んでみてください。

終わりに

筆者は今回初めて BlackHat に参加しました9。慣れない海外カンファレンスであったため、色々と苦労する点も有りましたが、Briefings 含め様々なコンテンツを楽しむことができました。また現地で他研究者とたくさん交流することができたのも、非常に良い経験になりました。このような研究成果を生み出し、カンファレンスで還元してくださっている研究者の皆様に、心から敬意を表します。

株式会社 Flatt Security では、セキュリティ系カンファレンスへの参加の支援制度10の運用や、そこで得た知見の検証などを積極的に行っています。もし自分もこのような活動を行いたい、興味がある、という方がいらっしゃったら、ぜひこちら (弊社採用情報ページ) をご覧ください。

また、WebのtoBプロダクトも開発中なので、こちらはWantedlyも是非ご参考になさってください。


  1. https://web.archive.org/web/20051103214640/http://www.watchfire.com/resources/HTTP-Request-Smuggling.pdf
  2. Bruce Schneier 氏が彼の 1999 年のエッセイ中で述べた "The worst enemy of security is complexity." という言葉は、ご存じの方も多いのではないでしょうか。筆者も今の Web を眺めては、この言葉を思い出すものです。
  3. 参考 … Dropbox の zxcvbn で発見された AC 脆弱性
  4. IDNA が提案される前から存在しているプロトコルが ASCII のみのラベルに依拠しているため、このような 2 つのラベルが存在しています。
  5. RFC3490
  6. このような変更の背景には、IDNA2003 が Unicode の特定バージョンに依存してしまっていたという過去があります。興味のある方は、IETF での議論を追ってみると良いかも知れません。
  7. U+2100 の他にも、同じような攻撃に利用できる Unicode 文字は存在します。
    1. Elsayed and A. Shosha, “Large scale detection of IDN domain name masquerading,” eCrime Res. Summit, eCrime, vol. 2018–May, pp. 1–11, 2018.
  8. 海外への渡航も初めてでした。
  9. この制度は社内ではギーク・ミーハー手当 … 略してギーハー手当と呼ばれています。