Node.jsとSocket.IOは初めてです。ドキュメントによると、クライアント側のコードは次のようなものです:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:3000');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
シンプルで簡単ですが、ローカルテストでは完全に問題ありませんが、サーバーのイベント情報を公開しているため、ライブページで本当に安全かどうかはわかりません。
このようなページで機密情報を非表示にするにはどうすればよいですか?
Socket.ioは WebSocket を作成し、WebSocketは通常のSame-Origin Policyルールに従います。ただし、Access-control-allow-Origin
HTTPヘッダーを使用して WebSocketをクロスオリジンリソースにする を作成することは可能です。これは一般にCORSとして知られています。何らかの理由でCORSを使用してクロスオリジンのWebSocketが作成された場合、これは WebSocketが信頼されていないドメインによってハイジャックされる可能性があります である可能性があります。
さらに、WebSocketは他のAPIと同様に、アプリケーションロジックを攻撃者に公開します。 OWASP Top 1 にあるような一般的なWebアプリケーションの脆弱性に対処するようにしてください。特に問題となるのは 安全でない直接オブジェクト参照 、 インジェクション攻撃 、および 壊れた認証とセッション管理 です。
この問題には2つの一般的な解決策があります。どちらのソリューションも、公開すべきではない情報を公開しないというアプローチに基づいています。これは、アプリケーションになんらかの認証メカニズムを実装する必要があることを意味します。新しいセッション(および新しい一時セッションキー)を作成するログインフォーム。言うまでもなく、https
/wss
の代わりにhttp
/ws
も使用する必要があります。
最初の方法は、公開イベントのみを公開し、プライベートイベントデータを別のチャネル(新しいHTTPリクエストなど)経由でフェッチすることです。これは、Stack Exchangeが受信トレイのライブ通知で行うことです。ソケットは、サブスクライバーに新しい受信トレイメッセージを通知するためにのみ使用されますが、実際のコンテンツは、ユーザーが通知バブルをクリックしたときにhttp(s)経由でのみフェッチされます。
2番目の方法は、ソケットのサーバー側を格納する前にSocket.IO接続を認証することです。 Socket.IOでは、query
オプションを介してハンドシェイクで追加情報を渡すことができます。サーバーでこの値を読み取り、認証が成功した場合にのみユーザーがソケットを作成できるようにします( 例 受け入れられた答えは、socket.io 0.9の場合、 ここを参照 はsocket.io 1.x)。このキーは、セッションCookieのように扱う必要があります。ユーザーがサインアウトすると、このキーに関連付けられたソケットが破棄され、トークンが無効になります。理想的には、このキーは1回だけ使用する(つまり、最初の使用後に無効にする)必要がありますが、接続が信頼できず、Socket.IOに再接続し続ける必要がある場合、これは実際にはうまくいきません。
ソケットを拒否する代わりに(方法2)、ソケットを受け入れ、認証の詳細を使用して、ユーザーがイベントへのサブスクライブまたはルームへの参加を許可されるかどうかを制御することもできます。クライアントは、サーバーでイベントを送信した場合にのみイベントを受信します。したがって、イベントを送信しない場合(たとえば、ユーザーがイベントがブロードキャストされる部屋にいないため)、情報の漏洩はありません。
すべてのセキュリティの質問と同様に、セキュリティの目的を説明する必要があります。誰から安全ですか?どのような種類のアクセスから安全ですか?望ましくないアクセスからどれほど安全である必要がありますか?情報の不要な閲覧者を防ぐために、どのレベルの認証と暗号化を追加してもよいですか?
上記で設定したスキームでは、次のことが可能です。
どのエージェントもWebSocketを使用してサーバーに接続し、「ニュース」イベントをサブスクライブできます。したがって、news
メッセージを使用してブロードキャストされる情報は誰でも利用できます。
実際、どのエージェントもWebSocketを使用してサーバーに接続し、接続されているすべてのソケットにブロードキャストするすべてのメッセージを読み取ることができます。これはnews
イベントに限定されません。サーバーがランダムに接続されたWebSocketにデータを送信する場合、ランダムなエージェントはWebSocketを介して接続し、その情報を読み取ることができます。
逆方向に送信されたデータ(クライアントからサーバーへ)に関しては、その情報は、接続をスヌーピングしている人(ISPで、インターネットを介してサーバーがあるデータセンターにデータを転送しているとき)のみが利用できます。サーバーまたはサーバーに物理的にアクセスできる人に到達する前に中央に配置します。このデータは、パケットが流れているトランスポートにアクセスしないと、外部のエージェントが簡単に利用できません。
データをより安全にする方法についての短い答えは、ほとんどのセキュリティの質問とほとんど同じです。
アクセスを保護するには、アクセスを許可する前に何らかの強力なログインを要求する必要があります。
暗号化(適切な証明書に裏打ちされたSSLなど)でトランスポートを保護します。
既に適切なセキュリティが導入されているチャネルで、セキュリティが必要な情報のみを送信します。
インターネット上には、サーバーベースのAPIや、独自のWebページからのみアクセスできるWebSocketアクセスなどはありません。 Webページからのアクセスは、インターネット上のランダムなエンドポイントからのアクセスにすぎず、通常、目的のブラウザーページ、独自の接続ツールを使用するハッカー、サイトにアクセスしようとしているインターネット上の不正なサーバーの間のアクセスに違いはありません。 。通常、違いはわかりません。サードパーティのアクセスをより困難にするためにいくつかのトリックがあります(使用する必要がある各Webページに絶え間なく変化する資格情報を含めるなど)が、上記の3つのセキュリティテナントがないと、実際には安全ではありません。