web-dev-qa-db-ja.com

WebSocketsに同一生成元ポリシーがないのはなぜですか? ws:// localhostに接続できるのはなぜですか?

アプリケーションのプロセス間通信にWebSocketを使用したい(Daemon <-> WebGUIおよびDaemon <-> FatClientなど)。テスト中に、websocket.orgのJavaScript WebSocketクライアント( http://www.websocket.org/echo経由でローカルで実行されているWebソケットサーバー(ws:// localhost:1234)に接続しようとしました。 .html )。

私の質問は次のとおりです。
これが可能なのはなぜですか?ブラウザにクロスオリジンポリシーが実装されていませんか(ここではLinuxのFF29)?

Websocket.orgが悪かった場合、ローカルWSサーバーと通信し、localhostから受信したすべてのメッセージを他のサーバーにリダイレクトしようとする可能性があるため、私は尋ねています:

ローカルWebSocketサーバーブラウザーEvil Webサーバー
 ws:// localhost:1234 at http://evil.tld 
 | | | 
 | | ------ [GET /]--------->|
 | | <----- [HTML + EvilJS] ---- | 
 | <------ [connect ws:// ..] ---- | | 
 | <---- [コミュニケーション]-> | | 
 | | ---- [邪悪な前進] ----> | 
 | | | 

ユースケース全体をテストしていませんが、websocket.orgが提供するJSからws:// localhostへの接続は間違いなく機能します。

73
binwiederhier

oberstetが質問に答えた 。ありがとうございました!残念ながら、これはコメントだったため、「正しい」とマークすることはできません。ブラウザは、アプリケーションがチェックできる「Origin」ヘッダーを送信します。

In Java [1]:

@Override 
 public void onOpen(WebSocket clientSocket、ClientHandshake handshake){
 String clientOrigin = handshake.getFieldValue( "Origin"); 
 
 if(clientOrigin == null ||!clientOrigin.equals(WEBSOCKET_ALLOWED_Origin_HEADER)){
 logger.log(Level.WARNING、 "クライアントは正しいOriginヘッダーを送信しませんでした:" + clientOrigin); 
 
 clientSocket.close(); 
 return; 
} 
 
 // ... 
}

[1]使用 https://github.com/TooTallNate/Java-WebSocket

39
binwiederhier

「なぜ?」に対処するには一部、ブラウザがAJAX呼び出しではなくWebSocketsに対してSame Origin Policy(CORSは緩和))を強制しない理由は、WebSocketsがcross-オリジンリクエストが確立され、SOPの影響を受けないため、CORSクライアント側チェックの歴史的な理由は当てはまりません。

AJAXの場合、包括的な単一オリジンポリシーの時代には、サーバーは認証されたブラウザーが異なるドメインからリクエストを送信することを期待していませんでした1、したがって、信頼できる場所からのリクエストであることを確認する必要はありませんでした2。 CORSのような後の緩和では、この前提に違反することで( CSRF攻撃 を有効に) 既存のアプリケーションを悪用する を回避するためにクライアント側のチェックが必要でした。

現在Webが発明されていて、今わかっていることを知っていれば、SOPもCORSもAJAXには必要なく、すべての検証が可能になる可能性がありますサーバーに残しました。

新しいテクノロジーであるWebSocketは、最初からクロスドメインシナリオをサポートするように設計されています。サーバーロジックを作成する人は、クロスリクエストの可能性を認識し、必要な検証を実行する必要があります。CORSのようにブラウザ側での手間がかかりません。


1 これは単純化です。リソース(<img>、<link>、および<script>タグを含む)およびフォーム送信に対するクロスオリジンGETリクエストPOSTリクエストは常にWebの基本機能として許可されていました。 -Origin AJAX要求が同じプロパティを持つ呼び出しも許可され、 simple cross-Origin requests と呼ばれます。ただし、コードでそのような要求から返されたデータにアクセスするにはサーバーのCORSヘッダーで明示的に許可されていない限り、許可されません。また、悪意のあるWebサイトからサーバーを保護するためにCSRFトークンが必要な主な理由は、これらの "シンプル" POST 。

2 実際、Refererヘッダーはスプーフィングされる可能性があるため、リクエストソースをチェックする安全な方法は利用できませんでした。オープンリダイレクトの脆弱性を使用します。これは、当時CSRFの脆弱性がどの程度理解されていなかったかを示しています。

36
staafl

WebSocketはドメイン間通信を行うことができ、SOP(同じオリジンポリシー)によって制限されません。

WebSocketがなくても、説明した同じセキュリティ問題が発生する可能性があります。

邪悪なJSは次のことができます。

  • Evil.tldへのURLを使用してscript/imageタグを作成し、クエリ文字列にデータを入れます。
  • フォームタグを作成し、フィールドにデータを入力して、フォームの「送信」アクションを呼び出し、HTTP POSTを実行します。これはクロスドメインにすることができます。 AJAXはSOPによって制限されますが、通常のHTTP POSTは制限されません。XSRFWebセキュリティの問題を確認してください。

何かがページにjavascriptを挿入した場合、または悪意のあるjavascriptを取得した場合、セキュリティは既に壊れています。

16
vtortola