私は現在、html5キャンバスとwebsocketを使用したゲームでWebページを構築しています。 server:3000で実行されているPerlで記述されたWebSocketサーバーがあります。サーバーにApacheもインストールし、ユーザーがアクセスできるWebサイトを作成しました: http:// server / 。このページのjavascriptは、ws:// server:3000へのWebSocketを作成します
接続が機能し、ブラウザからメッセージを送信して応答を取得できます。今のところ、すべてがdivに表示されています。私が送信するメッセージは今のところ「message:...」のみなので、サーバーはそれがメッセージであることを認識し、現在「ゲーム」に接続しているすべてのユーザーに「...」を出力します。
問題は、誰でもws:// server:3000に接続して適切なメッセージを送受信する独自のクライアントを作成できることです。このように、彼らは私のバックエンドを使用しますが、私のクライアントは使用しません(私は彼らに http:// server / からのみ再生してもらいたいです)。
クライアントのみが使用されていることを確認するにはどうすればよいですか?主な懸念は不正行為です。メッセージを送信し、受信したボットを解釈することで、ポートに接続して再生するボットを作成できます...この問題を解決するにはどうすればよいですか?
JettyWebサーバーを使用しています。
基本認証を使用しています。実装が簡単だったので、最初はこれを使いました。ただし、WebSocketによって提示される承認の問題を発見した後、基本的な承認は使用するのに適したメカニズムだと思います。
アップグレード要求ヘッダーには、認証データがハッシュされています。
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Authorization:Basic YWRtaW46cm9vdA==
Cache-Control:no-cache
Connection:Upgrade
私のWebSocketサーバーでは、OnMessageイベントごとに次のように呼び出します。
session.getUpgradeRequest().getUserPrincipal()
次に、この情報を使用して、データの処理が許可されているかどうかを判断できます。また、OnConnectイベントでソケットのオリジンを確認します。
session.getUpgradeRequest().getOrigin()
基本認証は機能しますここでこの回答が示すように: WebsocketsクライアントAPIのHTTPヘッダー
基本認証を使用すると、URLにユーザー名とパスワードを含めることができます。
ws://username:password@localhost:8888/
または、プロトコルとユーザー名またはその他のセッションIDを介してhashed/md5/sha1パスワードを送信するだけで独自のセキュリティを実装できます。 もちろん、クライアントも渡す前にトークンリクエストを送信するのは良いことです。
他の人が述べているように、自分のクライアント側のコードだけがWebSocketと通信するように強制することはできません。ただし、WebSocket接続をWebサーバーの残りの部分に関連付けることができます。
たとえば、Webサーバーが提供するログインフォームを介してプレーヤーを認証するとします。次に、ログインが成功すると、クライアントに渡すトークンを生成し、クライアントコードに、WebSocket接続ハンドラーで確認できるクエリパラメーターとしてトークンを渡してもらいます。
http://server/play
_に投稿する(token, username, timestamp)
_としてデータベースに配置しますmyGame.start(<literaltoken>)
が含まれますws://server:3000/?token=<token>
_に接続しますサーバー側の状態を維持する必要がない場合は、代わりに、サーバー側の秘密鍵を使用して、トークンを_(username, timestamp)
_の暗号化および署名されたblobにし、WebSocketハンドラーでそのblobを復号化/検証できます。
あなたが求めていることを達成することは不可能です。サードパーティが無許可のクライアントを作成することを困難にするための措置を講じることができますが、最終的にはサードパーティが使用できる限りあなたの正当なクライアント、彼らはいつでもそれが何をするかを見てそれをコピーすることができます、そしてあなたがそれを止めるためにあなたができることは何もありません。
ただし、それを難しくするためにできることがあります。
ただし、これを行ったとしても、断固とした攻撃者はJavaScriptを復号化して難読化を解除し、メッセージの暗号化に使用しているキーを見つけて、プレーンテキストに戻し、リバースエンジニアリングを行うことができます。
非常に簡単だと思います。websocketconnectにヘッダーを追加し、それをホスト名などにして、暗号化された値を割り当て、WebSocket接続がWebscoketサーバーに対して行われるたびにこの暗号化された値を確認します。
私も同じ問題に直面しました。 Java/Flashゲーム用のHTML5クライアントを作成するためにwebsocket-> socketプロキシを作成しています。承認段階で自作の暗号化を使用して、レガシークライアントであることを確認します。
Jsファイルのソースが開いているのと同じ暗号化コードを挿入するのは安全ではないと思います。今のところ、WSプロキシにその認証アルゴリズムを隠しましたが、どういうわけか、許可されていないWSクライアントを検出する必要があります:)
Webサイトの一時セッションIDを使用して、WebSocketクライアントがWebサイトで承認されているかどうかを確認しています。しかし、それは信頼できません。
また、クライアント(ブラウザ)が動的に生成されたjavascriptファイルをダウンロードして実行し、WebSocketサーバーに送信して、有効な結果を確認できるようにするメカニズムについても考えています。そうすれば、クライアントがブラウザ(またはJSエンジンを備えた複雑なボット:))であることを確認できます。とにかく、それは私の考えであり、実装するのは難しいようですが、私はまだそれを試していません。
Webの性質上、この種のことは(ハッカーにとっては)簡単になり、アプリケーションやWebサイトを構築する人にとっては難しくなります。通常、「リファラー」を使用して、リクエストがサイト/ドメインから送信されていることを確認します。これは絶対確実ではありませんが、ほとんどの場合に機能します。
HTML 5では、ハイパーリンクがリファラーを送信する必要がないことを知っています。これは、WebSocketなども含めるように変更される可能性があります。
ある種のソルトでメッセージを暗号化し、そのハッシュをメッセージと一緒に送信してサーバー上のハッシュに対してメッセージを検証したとしても、クライアント側のコードは潜在的に利用可能であり、誰にでも見えるため、解読される可能性がありますあなたの論理。
WebSocketの仕様は常に変化しています。一部のブラウザは、当面の間、WebSocketサポートを無効にするか削除しました。
WebSocketハンドシェイクプロトコル(Sec-WebSocket-Key1とSec-WebSocket-Key2を使用)は、物事を少し安全にするはずでしたが、この仕様はほとんどのプロキシサーバーでは機能しません。ここで仕様を読むことができます http://www.whatwg.org/specs/web-socket-protocol/
ハンドシェイクプロトコルは、まったく異なる目的で導入されたことに注意してください。それはあなたが求めているものではなく、サーバーがハンドシェイクで応答しない限りクライアントがサーバーと通信できないように、クライアントがサーバーをハッキングするのを防ぐためです。ただし、あなたの場合、クライアントを知らずにハンドシェイクで応答する必要があります。
ですから、あなたが必要なことをするための信頼できる方法はまだないと思います。