web-dev-qa-db-ja.com

WebSocketフレームのマスクとは何ですか?

私はwebsocketの実装に取り​​組んでいますが、フレーム内のマスクの意味がわかりません。

誰かがそれが何をするのか、なぜそれが推奨されるのかを説明してもらえますか?

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-------+-+-------------+-------------------------------+
 |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 | |1|2|3|       |K|             |                               |
 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 |     Extended payload length continued, if payload len == 127  |
 + - - - - - - - - - - - - - - - +-------------------------------+
 |                               |Masking-key, if MASK set to 1  |
 +-------------------------------+-------------------------------+
 | Masking-key (continued)       |          Payload Data         |
 +-------------------------------- - - - - - - - - - - - - - - - +
 :                     Payload Data continued ...                :
 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                     Payload Data continued ...                |
 +---------------------------------------------------------------+
50
bodokaiser

WebsocketはRFC6455で定義されており、 セクション5.3 に次のように記載されています。

マスキングキーの予測不可能性は、悪意のあるアプリケーションの作成者がワイヤに表示されるバイトを選択できないようにするために不可欠です。

Websocketに関する ブログエントリで 次の説明を見つけました。

masking-key(32ビット):マスクビットが設定されている場合(サーバー側に書き込む場合は信頼してください)、ここでペイロードのxorに使用される符号なしバイトを読み取ることができます。 これは、クライアント側からの攻撃者がくだらないプロキシを悪用できないようにするために使用されます

しかし、最も明確な答えは、 メーリングリストアーカイブ で見つけました。ジョンタンプリンは次のように述べています。

基本的に、WebSocketsは、クライアントで実行される敵対的なコード、サーバーの完全な敵対的制御があり、信頼できる唯一の部分がクライアントブラウザーである場合でも、ネットワークインフラストラクチャを保護する必要があるという点でユニークです。 ブラウザに各フレームのランダムマスクを生成させることにより、悪意のあるクライアントコードは、ワイヤに表示されるバイトパターンを選択できず、それを使用して脆弱なネットワークインフラストラクチャを攻撃できません

Kmkaplanが述べたように、攻撃ベクトルはRFCの セクション10.3 で説明されています。
これは、プロキシキャッシュポイズニング攻撃を防ぐための手段です(攻撃については Paperを参照してください )。それがすることは、ランダム性を作り出すことです。ランダムマスキングキーを使用してペイロードをXORとする必要があります。

ちなみに、これは推奨されるだけではありません。 obligatoryです。

55
Enno Gröper

この記事 から:

クライアントからサーバーへのWebSocketトラフィックのマスキングが必要なのは、悪意のあるコードが壊れたプロキシに間違った動作をさせ、これを何らかの攻撃として使用する可能性が低いためです。これが実際に発生することを誰も証明していませんが、それが発生する可能性があるため、ブラウザベンダーが動揺するのに十分な理由であるため、攻撃として使用される可能性を排除するためにマスキングが追加されました。

そのため、攻撃者がブラウザで実行されるJavaScriptコードとバックエンドサーバーの両方を侵害できると仮定すると、これらの2つのエンドポイント間で送信されるバイトシーケンスが、破損したプロキシを混乱させる可能性のある特別な方法で作成されるのを防ぐように設計されていますこれらの2つのエンドポイント間(これは、壊れているため、Websocketストリームを実際にはHTTPとして解釈すべきではないがHTTPとして解釈しようとするプロキシを意味します)。

ブラウザー(ブラウザーのJavaScriptコードではなく)は、メッセージを送信するために使用されるランダムに生成されたマスクについて最終決定権を持っているため、攻撃者はプロキシが見る可能性のあるバイトの最終ストリームを知ることができません。

WebSocketストリームが暗号化されている場合(そうあるべき)、マスクは冗長であることに注意してください。 記事 PythonのFlaskの著者から:

なぜマスキングがあるのですか?どうやら十分に壊れたインフラストラクチャがあり、アップグレードヘッダーを通過させてから、残りの接続を2番目のHTTPリクエストとして処理し、キャッシュに詰め込むためです。私はこれについて何も言いません。いずれにせよ、それに対する防御は、基本的にマスキングキーとして強力な32ビットの乱数です。または、知っている... TLSを使用し、くだらないプロキシを使用しないでください。

13
Martin Konecny