もしwebセキュリティのエンジニアがrfc7540の「http/2アプリ」をweb診断したら

57
もも Web ももももももももももももも RFC7540 もHTTP/2 もももも Web ももももも ももも もも R

Upload: abendcve99990001

Post on 05-Aug-2015

3.849 views

Category:

Engineering


5 download

TRANSCRIPT

Page 1: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

もし Web セキュリティのエンジニアが RFC7540 の「 HTTP/2 アプリ」を Web診断したら略して「もし R 」

Page 2: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

自己紹介Twitter :  abend@number3to4

Web セキュリティエンジニア

Page 3: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

宣伝7/26 (日) に開催される JULY TECH FESTA にて、「フリーでできるセキュリティチェック」というタイトルにて、プレゼンをさせていただきます。

”無料”のツールを利用して、ラクにセキュリティチェックを行うためのノウハウをご紹介いたします。

インフラエンジニア、運用を担当されているエンジニア向けの内容となっています。

http://2015.techfesta.jp/

Page 4: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

HTTP/2 ってHTTP ( HyperperText Transfer Protocol )の最新バージョンにあたり、 HTTP/1.1から 16 年ぶりのアップデート。 HTTP/2 については RFC7540 、関連する HPACK はRFC7541 でリリースされました。

HTTP/1.1 と比較すると HTTP/2 は複雑になっています。HTTP/1.1 との違いはこんな感じ。

①  多重化②  バイナリメッセージ③  ヘッダ圧縮( HPACK )④  フロー制御⑤  優先度⑥  依存関係⑦   Server Push

Page 5: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

nghttp2 ってHTTP/2 に対応した Web サーバ、 Web クライアント、 Proxy 機能を有する。通信内容の確認は、 hexdump オプションを指定することで確認することが可能。

https://nghttp2.org/

Page 6: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

①  多重化HTTP/1.X では、 1 つの TCP コネクションで 1 つのリクエストおよびレスポンスをやりとりしていた。 HTTP/2 では、 stream という概念により 1 つの TCP コネクションで複数のリクエストおよびレスポンスをやりとりできるようなった。

stream

Stream_id :偶数

Stream_id :奇数

Stream_id : 0

クライアントサーバ

StreamID0 :コネクション制御用奇数:クライアントが開始偶数:サーバが開始

コネクション

Page 7: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  バイナリメッセージHTTP フレームが新たに定義され、 stream 上でやりとりをする。フレームタイプによって Frame Payload のフォーマットが変わる。フレームヘッダは 9byte 。

フレームヘッダ

HEADERS フレーム

Page 8: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  バイナリメッセージリクエスト、レスポンスヘッダがバイナリベースとなっている。

Nghttp でアクセスした際の dump 結果。赤枠箇所がリクエストの HEADERS フレーム。

Page 9: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  バイナリメッセージリクエストの HEADERS フレーム。

00   00   26   01   25   00   00   00     0d   00   00   00   0b   0f  82   84 87   41   8b   0b   e2   5c   2e   3c     b8   5b   7d   70   b2   cf  53   03

2a   2f   2a   90   7a   89   aa   69     d2   9a   c4   c0   57   02   e0緑箇所の 3byte 「 00 00 26 」がフレームサイズで 38byte ( 0x26 )最初の 9byte (固定長)は、フレームヘッダ。

青箇所の「 01 」がフレームタイプを表しており、 0x01 は HEADERS フレーム。黄色箇所の「 25 」は Flag で詳細は RFC7540 へ。

茶色箇所の 4byte (正確には 31bit 分)は Stream ID で、この場合は 13 。

Page 10: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  バイナリメッセージリクエストの HEADERS フレームペイロード(赤箇所)

00   00   26   01   25   00   00   00     0d   00   00   00   0b   0f  82   84 87   41   8b   0b   e2   5c   2e   3c     b8   5b   7d   70   b2   cf  53   03

2a   2f   2a   90   7a   89   aa   69     d2   9a   c4   c0   57   02   e0青箇所は依存先の Stream ID を指している。

白箇所で Priority フラグ( 0x20 )がセットされた場合にのみ、青箇所と緑箇所が出力される。

緑箇所は weight で、「 0f 」の場合、 15+1=16 となる。

Page 11: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

③  ヘッダ圧縮( HPACK )HTTP/2 はヘッダ圧縮のために HPACK ( RFC7541 )を採用しています。ハフマン符号や静的テーブルと動的テーブルを用いて、圧縮しています。

Index の場合、 7bit の値がリクエスト・レスポンスヘッダのヘッダ名、値を指している。「 : 」から始まるヘッダ名は HTTP/2 のために作られた疑似ヘッダフィールドです。

Page 12: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

③  ヘッダ圧縮( HPACK )さっきの Header Block の場合

00   00   26   01   25   00   00   00     0d   00   00   00   0b   0f  82   84 87   41   8b   0b   e2   5c   2e   3c     b8   5b   7d   70   b2   cf  53   03

2a   2f   2a   90   7a   89   aa   69     d2   9a   c4   c0   57   02   e00x82 ( 1000 0010 )で Index の 2 を指しており、「 :method: GET 」を意味します。同様に 0x84 、 0x87 は、それぞれ Index が 4 、 7 を指しています。

Index 4  ・・・  :path: /Index 7  ・・・  :scheme: https

Page 13: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

③  ヘッダ圧縮( HPACK )bit により、どういう意味なのか変わってくる。

Index は事前に定義されたヘッダ名の値をセットする。 0x41 の場合、 Index が 1 である :authority を指す。

2byte 目(緑箇所)は、上位 bit がハフマンエンコーディングの有無を指定し、値長を指定している( 11byte )。

00   00   26   01   25   00   00   00     0d   00   00   00   0b   0f  82   84 87   41   8b   0b   e2   5c   2e   3c     b8   5b   7d   70   b2   cf  53   03

2a   2f   2a   90   7a   89   aa   69     d2   9a   c4   c0   57   02   e0

Page 14: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

③  ヘッダ圧縮( HPACK ):authority: ヘッダの値は、赤箇所の byte 列( 11byte 分)になる。

この byte 列はハフマンエンコーディングされているため、このままでは可視できるものではないので、ハフマンでコーディングを行う必要がある。

00   00   26   01   25   00   00   00     0d   00   00   00   0b   0f  82   84 87   41   8b   0b   e2   5c   2e   3c     b8   5b   7d   70   b2   cf  53   03

2a   2f   2a   90   7a   89   aa   69     d2   9a   c4   c0   57   02   e0

Page 15: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

③  ヘッダ圧縮( HPACK )まずは、 11byte を 2 進数に変換し、結合する。

RFC7541 で定義されているテーブルから戻してあげればいい。赤箇所の「 00001 」は 1 を意味しており、白は9 、青は 2 を意味する。

これを繰り返すと「 192.168.159.133 」となる。緑箇所は余りで 1 で padding されている。

0000101111100010010111000010111000111100101110000101101101111101011100001011001011001111

Page 16: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

④  フロー制御HTTP/2 では 1 つのコネクションで複数の stream が通信できる。複数の stream が一斉に大量の通信をはじめたら・・・。

俺、通信するっ!! じゃ、俺も俺も。 じゃ、俺も俺も。

誰も「どうぞ、どうぞ」を言わないと、重要な通信が行えなくなってしまう。

どうぞ、そうぞ どうぞ、そうぞ えっ!?

Page 17: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

④  フロー制御ウィンドウサイズによるフロー制御が存在しており、優先度にも応じて通信を行う。ただし、フロー制御の対象となるのは、 DATA フレームのみ。

コネクションの使用可能なウィンドウサイズ: 65535

Stream ごとの使用可能なウィンドウサイズ: 65535

使用可能な量を使い切ってしまった場合、受信者側から WINDOW_UPDATEを受け取ることで、使用可能な量を追加することができる。

クライアントサーバ

Page 18: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

④  フロー制御たとえば、 237byte のデータを StreamID が 1 のウィンドウサイズ 127byte の設定で通信した場合・・・

2.  サーバが 237byte のデータのうち、 127byte を send

クライアントサーバ

コネクション ウィンドウサイズ: 65535

Stream ID:1 ウィンドウサイズ: 127

1.  クライアントが Initial Window Size を 127byte へ変更を send

コネクション ウィンドウサイズ: 65535

StreamID :1 ウィンドウサイズ: 127

クライアントサーバ

Page 19: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

④  フロー制御

4.  サーバが残りの 110byte を send

クライアントサーバ

コネクション ウィンドウサイズ: 65408

Stream ID:1 ウィンドウサイズ: 127

3.  クライアントが WINDOW_UPDATE(StreamID:1)127byte を send

コネクション ウィンドウサイズ: 65408

Stream ID:1 ウィンドウサイズ: 0

クライアントサーバ

Page 20: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

④  フロー制御Initial Window Size は、 SETTING フレームで指定します。

00   00   0c   04   00   00   00   00     00   00   03   00   00  00   64   0004   00   00   00   7f

赤箇所 9byte はフレームヘッダ。黄色箇所以降が SETTING フレームのペイロード。

2byte の識別子と 4byte の値の計 6byte単位で構成される。黄色箇所 0x03 は、 SETTINGS_MAX_CONCURRENT_STREAMS を意味し、値は緑箇所の 0x64(100) 。 0x04 が SETTINGS_INITIAL_WINDOW_SIZE で、 0x07(127) 。

※ SETTINGS_INITIAL_WINDOW_SIZE はオプションで強制的に 0x07 に指定してます。

Page 21: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

④  フロー制御WINDOW_UPDATE は、 WINDOW_UPDATE フレームで実行されます。

00   00   04   08   00   00   00   00     0d   00   00   00   1f

WINDOW_UPDATE は、「コネクションに対して」と「 Stream に対して」行うことが可能で、フレームヘッダで指定する Stream ID が 0 の場合、「コネクションに対して」、指定する Window Size が追加される。「 Stream に対して」行う場合は該当する Stream ID を指定する必要がある。両方に対して行う必要がある場合はそれぞれの WINDOW_UPDATE フレームを送信する必要がある。

Page 22: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

⑤  優先度各 Stream が Window Size の上限まで使い切ることがないように、 Stream に対して優先度 (Wight) をつけて、その割合に応じて通信を行う。

値は 1 から 256 の整数で指定することが可能です。 Default は 16 です。

StreamID:1   Wight:12StreamID:3   Wight:3

この場合、 StreamID:1 は全体の 5 分の 4 の割合で通信を行います。

非常に参考になりました。HTTP/2 Deep Dive: Priority & Server Push by Moto Ishizawahttps://speakerdeck.com/summerwind/2-deep-dive-priority-and-server-push

Page 23: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

⑤  優先度優先度の指定は、 PRIORITY フレームを用いて行うことが可能です。

00   00   05   02   00   00   00   00     03   00   00   00   00   c8

赤箇所はフレームヘッダ。青箇所は依存する StreamID を指定し、この場合は 0 を指していている。緑箇所が該当 Stream(StreamID:3) の優先度で、 0xc8(200)+1=201 が優先度となる。

Page 24: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

⑥  依存関係各 Stream は、他の Stream と依存関係を持ちます。

ルートには StreamID:0 がセットされ、依存される StreamID のほうが優先してリソースの割り当てを行われます。

StreamID:0

StreamID:1 StreamID:3

StreamID:5 StreamID:7

Page 25: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

⑦   Server Push通常、クライアントからリクエストを送信し、それに対してレスポンスを返すが、 Server Push はクライアントからのリクエストを受けずにサーバがレスポンスを返す。

クライアント サーバ

リクエスト

レスポンス

Server Push のレスポンスは、クライアントが送信すると予定されるリクエストとデータを返します。データはクライアントでキャッシュされます。

Page 26: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

⑦   Server PushServer Push するために、サーバからクライアントに PUSH_PROMISE フレームで通知しておく必要があります。

Promissed Stream ID は、 Server Push され StreamID がセットされる。サーバが起点となるため、この値は偶数となる。また、 Header Block Fragment には予定されるリクエストをセットされます。

Page 27: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

⑦   Server PushServer Push するために、サーバからクライアントに PUSH_PROMISE フレームで通知しておく必要があります。

00   00   18   05   04   00   00   00     0d   00   00   00   02   82  04   8761   09   f5   41   57   22   11   87     41   87   08   9d   5c   0b  81   70ff赤箇所はフレームヘッダ。緑箇所は、 Server Push する StreamID で ID:2 を指定。水色箇所は、予定されるリクエストヘッダになっており、 HEADERS フレームと同様にデコード可能。

Page 28: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

Web 診断ってWeb アプリケーションの脆弱性の有無を検査することを Web 診断としています。Web 診断では、基本的に Proxy ツールを用いて行います。

Proxy ツールで検査パターンを付加してリクエストし、そのレスポンスの内容によって脆弱性の有無を判断します。

リクエスト

Web サーバクライアント検査パターンを付加する。 Proxy ツール

レスポンス

Page 29: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

Web 診断ってProxy ツールを使う理由は、ブラウザで操作できる内容が限られているためです。

都道府県:

性別:

都道府県:

性別: 男 女

東京都 (ブラウザ上で)入力形式が固定化されている場合に Proxy ツールを用いて、入力値を変更します。

Page 30: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

Web 診断ってProxy ツールのひとつに Burp Suite があります。Java で動作し、一部の機能は有償版のみとなりますが、基本的にフリーで使えるツールです。

リクエストを Intercept して変更することで、ブラウザでは変更できないパラメータも変更可能となります。

Page 31: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

結論HTTP/2 のアプリに対して、 Burp Suite でアクセスしてみた。

Burp Suite は、 HTTP/2 に対応していないのでできなかった。

Page 32: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

じゃあ、どうすんのソースとか見てたら、 nghttpx という Proxy 機能があることに気づいたのでこれを活用することに。

クライアント Proxy ツールHTTP/1.1 HTTP/2

nghttpxHTTP/1.1

こうすれば既存の仕組みのまま、 HTTP/2 アプリにも接続可能。

HTTP/2 アプリ

Page 33: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

試してみたNghttp2 を Proxy として動作させることで、 Burp Suite でもアクセスできるようになった。nghttpx --client -f0.0.0.0,8080 –b[HTTP2 サーバの IP],443 -k -o -LINFO

Page 34: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

これで脆弱性見つけられるnghttp2 には、アプリケーションサーバとしての機能がないため、以下、構成で診断が行えるか確認することに。

クライアント Proxy ツールHTTP/1.1

HTTP/2

nghttpxHTTP/1.1

Web アプリ

HTTP/1.1nghttpx

Page 35: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

当然見つかるHTTP/1.X と同様に何も変わることなく、 XSS を見つけることができた。

Page 36: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

じゃあ、すべての脆弱性も?HTTP ヘッダインジェクションはどうなるのだろうか。

脆弱なサイト一般利用者

Proxy Server

攻撃者

キャッシュが汚染される

メールやページ書込みによるリンク

XSSと同じ被害

Page 37: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

なぜ、 HTTP ヘッダインジェクションなのか

HTTP/2 だとレスポンスヘッダ(リクエストヘッダもだけど)はバイナリになるため、以下の行為ができないのではないかと考えた。

①  任意のヘッダ挿入  勝手に Set-Cookie とセットされる可能性がある。

②  レスポンススプリッティング   Proxy サーバに不正な内容をキャッシュさせられる可能性がある。

Page 38: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

なぜ、 HTTP ヘッダインジェクションなのか

検証するにあたり、脆弱なソースを用意した。※オープンリダイレクタも存在します。

#!/usr/bin/perluse utf8;use strict;use CGI;

my $cgi = new CGI;my $url = $cgi->param('url');

print "Status: 302 Moved\n";print "Content-Type: text/html; charset=UTF-8\n";print "Location: $url\n";print "\n";print "<hmtl>\n";print "<body>\n";print "redirect done!!\n";print "</body>\n";print "</hmtl>\n";exit;

Page 39: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

①  任意のヘッダ挿入HTTP/2 の場合、 HPACK を用いてヘッダの圧縮を行っているため、脆弱性を悪用してヘッダにインジェクトしようとしても、ただの文字列として処理されてしまうのではないかと推測した。

<レスポンス>HTTP/1.1 302 FoundDate: Thu, 25 Jun 2015 00:17:28 GMTSet-Cookie: a=aLocation: http://www.yahoo.co.jp以下略

<リクエスト>GET http://192.168.159.152:8433/redirect.cgi?url=http://www.yahoo.co.jp%0a%0dSet-Cookie:a=a HTTP/1.1以下略

脆弱だった。。。

Page 40: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

①  任意のヘッダ挿入なぜこうなったのか。

<推測です>

今回の構成の場合、バックエンドサーバである脆弱サーバで改行が評価されヘッダに挿入されたレスポンスをそのまま HTTP/2 へ返すために、 HTTP/2 にはまったく関係がなく、とめることはできないのではないかと推測しています。

Page 41: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティングHTTP/2 では、レスポンスヘッダとレスポンスボディはそれぞれ違うフレームとして送信されるため、レスポンスを分割したとしてもキャッシュされないのではないかと推測。<リクエスト>GET http://192.168.159.152:8433/redirect.cgi?url=http://www.yahoo.co.jp%0a%0dContent-Length:0%0a%0d%0a%0dHTTP/1.1%20200%20OK%0a%0d%0a%0d<html><body>inject</body></html> HTTP/1.1Host: 192.168.159.152:8433以下略

<赤字箇所の URL デコード結果>改行Content-Length:0改行改行HTTP/1.1 200 OK

<html><body>inject</body></html>

Page 42: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング結果は・・・。HTTP/1.0 302 Moved TemporarilyDate: Thu, 25 Jun 2015 16:57:28 GMTLocation: http://www.yahoo.co.jpContent-Length: 100Content-Type: text/html; charset=UTF-8Connection: keep-alive

HTTP/1.1 200 OK

<html><body>inject</body></html>

<hmtl><body>redirect done!!</body></hmtl>

プログラムがそもそも意図した通りになっていなかった。。。

Page 43: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング※20015/6/27に内容を追加してます。

意図した通りのレスポンスになっていないため、 python で強制的にレスポンススプリッティングした結果が HTTP/2(nghttpx) ではどのように評価されるか検証してみた。

参考http://qiita.com/otoyo/items/98098e927797272d0a39

プログラムは一部抜粋self.wfile.write("HTTP/1.1 302 Found\r\n")self.wfile.write("Content-Type: text/html; charset=utf-8\r\n")self.wfile.write("Location: http://www.yahoo.co.jp\r\n")self.wfile.write("Content-Length:0\r\n")self.wfile.write("\r\n")self.wfile.write("HTTP/1.1 200 OK\r\n")self.wfile.write("\r\n")self.wfile.write("<html><body>inject</body></html>\r\n")

Page 44: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

Python サーバにアクセスすると以下のレスポンスが常に返される。

HTTP/1.1 302 FoundContent-Type: text/html; charset=utf-8Location: http://www.yahoo.co.jpContent-Length: 0

HTTP/1.1 200 OK

<html><body>inject</body></html>

※20015/6/27に内容を追加してます。

青字箇所がレスポンススプリッティングされることを想定したレスポンス。

Page 45: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

ブラウザ →  Burp Suite  → フォワードプロキシ (nghttpx)  → リバースプロキシ (nghttpx)  →  Python サーバという順でアクセスした結果。

HTTP/1.1 302 FoundDate: Sat, 27 Jun 2015 08:10:08 GMTLocation: http://www.yahoo.co.jpVary: Accept-EncodingContent-Length: 0Content-Type: text/html; charset=UTF-8Server: nghttpx nghttp2/1.0.4Via: 1.1 nghttpx, 2 nghttpx

2 つ目のレスポンスがなくなっている。

※20015/6/27に内容を追加してます。

Page 46: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

リバースプロキシ (nghttpx) のログは、大きく 4 つのポイントがあります。

1. フォワードプロキシ (nghttpx) からの HTTP/2 の GET リクエスト2. Python サーバへの HTTP/1.1 の GET リクエスト3. Python サーバからの HTTP/1.1 のレスポンス4. フォワードプロキシ (nghttpx) への HTTP/2 のレスポンス

※20015/6/27に内容を追加してます。

Page 47: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

1. フォワードプロキシ (nghttpx) からの HTTP/2 の GET リクエスト

:method: GET:scheme: http:authority: リバースプロキシの IP:path: /user-agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8accept-language: ja,en-US;q=0.7,en;q=0.3accept-encoding: gzip, deflatex-forwarded-proto: httpvia: 1.1 nghttpx

※20015/6/27に内容を追加してます。

Page 48: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

2. Python サーバへの HTTP/1.1 の GET リクエスト

GET http:// リバースプロキシの IP/ HTTP/1.1Host: リバースプロキシの IPUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: ja,en-US;q=0.7,en;q=0.3Accept-Encoding: gzip, deflateVia: 1.1 nghttpx, 2 nghttpx

※20015/6/27に内容を追加してます。

Page 49: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

3. Python サーバからの HTTP/1.1 のレスポンス

:status: 302content-type: text/html; charset=utf-8location: http://www.yahoo.co.jpcontent-length: 0via: 1.1 nghttpx

※20015/6/27に内容を追加してます。

※疑似ヘッダフィールド「 :status 」が出力されている。理由は不明。

Page 50: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

4. フォワードプロキシ (nghttpx) への HTTP/2 のレスポンス[2805.766] send HEADERS frame <length=27, flags=0x04, stream_id=5> ; END_HEADERS (padlen=0) ; First response header :status: 302 content-type: text/html; charset=utf-8 location: http://www.yahoo.co.jp content-length: 0 via: 1.1 nghttpx[2805.766] send DATA frame <length=0, flags=0x01, stream_id=5> ; END_STREAM

※20015/6/27に内容を追加してます。

レスポンスは、 HEADERS フレームと DATA フレームのみで、 DATA フレームのサイズも 0 となっている。

Page 51: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

②  レスポンススプリッティング

レスポンススプリッティングした「 HTTP/1.1 200 OK 」のレスポンス自体は認識されずに、破棄されていると思われる。

※20015/6/27に内容を追加してます。

Nghttpx を介すことで、レスポンススプリッティングされる可能性は減ると思うが、実装状況にも依存すると思われるため、 HTTP/2 だからセキュアになるということではないと思う。

Page 52: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

まとめ

Page 53: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

大事なことなので 2 度言います。

Page 54: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

宣伝7/26 (日) に開催される JULY TECH FESTA にて、「フリーでできるセキュリティチェック」というタイトルにて、プレゼンをさせていただきます。

”無料”のツールを利用して、ラクにセキュリティチェックを行うためのノウハウをご紹介いたします。

インフラエンジニア、運用を担当されているエンジニア向けの内容となっています。

http://2015.techfesta.jp/

Page 55: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

・ HTTP/2 は以前のバージョンと比較すると複雑になり、 telnet とかで試すことが できなくなった。

まとめ

・ HTTP/2 を使えば安全というわけではなく、 Web アプリケーションはこれまで 通りセキュリティ対策はとる必要はある。

・ hexdump した結果を何度も見ていると、だんだんフレームが見えてくる。

Page 56: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

ちなみに前から疑問だったのだが・・・。

HTTP/2 コネクションの初期設定確立のために、 24byte の固定されたコネクションプリフェイスをサーバが送信する。

「 HTTP/2.0 」だと!?正式名称は「 HTTP/2 」 or 「 HTTP2 」じゃないのか。って、前から??でした。

Page 57: もしWebセキュリティのエンジニアがRFC7540の「HTTP/2アプリ」をWeb診断したら

参考資料RFC7540https://http2.github.io/http2-spec/http://summerwind.jp/docs/rfc7540/  (日本語訳)

RFC7541http://www.rfc-editor.org/rfc/rfc7541.txthttp://syucream.github.io/hpack-spec-ja/rfc7541-ja.html  (日本語訳)

HTTP/2 Frequently Asked Questionshttp://http2.info/faq.html#why-is-http2-multiplexed

HTTP2 Advent Calendar 2014http://qiita.com/advent-calendar/2014/http2

HTTP/2.0 のインパクトhttps://www.janog.gr.jp/meeting/janog32/doc/janog32-http2.0-shimizu-01.pdf

HTTP/2 入門http://www.slideshare.net/techblogyahoo/http2-35029629

HTTP/2 Deep Dive: Priority & Server Pushhttps://speakerdeck.com/summerwind/2-deep-dive-priority-and-server-push