WebSocket server doesn't properly handle protocol mistakes.
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 45/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 停滞
- 技術スタック
- scala
- 領域
- networking
調査の方向性
package.scala:26 の org.http4s.websocket.package.makeFrame から始め、失敗する前に FrameTranscoder.bufferToFrame が opcode をどのように処理するかを追跡します。予約済み opcode の動作を RFC 6455 section 5.2 と比較します。完了の条件は、不正な WebSocket フレームが MatchError を露出させずに接続を失敗させ、理解しやすい処理を生成することです。
索引モデルが issue の本文から書いたものです。
説明
Unfortunately, I don't know how exactly to reproduce this error.
The problem is that when I ran a local WebSocket server it was closing all incoming connections and printing the next stack trace:
scala.MatchError: 7 (of class java.lang.Integer)
at org.http4s.websocket.package$.makeFrame(package.scala:26)
at org.http4s.websocket.FrameTranscoder.bufferToFrame(FrameTranscoder.scala:165)
at org.http4s.server.blaze.WebSocketDecoder.bufferToMessage(WebSocketDecoder.scala:30)
at org.http4s.blaze.pipeline.stages.ByteToObjectStage.$anonfun$readAndDecodeLoop$1(ByteToObjectStage.scala:85)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at org.http4s.blaze.util.Execution$ThreadLocalTrampoline.run(Execution.scala:108)
at org.http4s.blaze.util.Execution$ThreadLocalTrampoline.execute(Execution.scala:94)
at org.http4s.blaze.util.Execution$$anon$2.execute(Execution.scala:53)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
at scala.concurrent.impl.Promise$DefaultPromise.dispatchOrAddCallback(Promise.scala:312)
at scala.concurrent.impl.Promise$DefaultPromise.onComplete(Promise.scala:303)
at org.http4s.blaze.pipeline.stages.ByteToObjectStage.readAndDecodeLoop(ByteToObjectStage.scala:99)
at org.http4s.blaze.pipeline.stages.ByteToObjectStage.startReadDecode(ByteToObjectStage.scala:72)
at org.http4s.blaze.pipeline.stages.ByteToObjectStage.readRequest(ByteToObjectStage.scala:68)
at org.http4s.blaze.pipeline.stages.ByteToObjectStage.readRequest$(ByteToObjectStage.scala:56)
at org.http4s.server.blaze.WebSocketDecoder.readRequest(WebSocketDecoder.scala:8)
at org.http4s.blaze.pipeline.Tail.channelRead(Stages.scala:88)
at org.http4s.blaze.pipeline.Tail.channelRead$(Stages.scala:85)
at org.http4s.server.blaze.WSFrameAggregator.channelRead(WSFrameAggregator.scala:16)
at org.http4s.server.blaze.WSFrameAggregator.readRequest(WSFrameAggregator.scala:24)
at org.http4s.blaze.pipeline.Tail.channelRead(Stages.scala:88)
at org.http4s.blaze.pipeline.Tail.channelRead$(Stages.scala:85)
at org.http4s.blazecore.websocket.Http4sWSStage.channelRead(Http4sWSStage.scala:18)
at org.http4s.blazecore.websocket.Http4sWSStage.$anonfun$readFrameTrampoline$1(Http4sWSStage.scala:54)
at org.http4s.blazecore.websocket.Http4sWSStage.$anonfun$readFrameTrampoline$1$adapted(Http4sWSStage.scala:53)
at monix.eval.internal.TaskCreate$.$anonfun$async$1(TaskCreate.scala:124)
at monix.eval.internal.TaskCreate$.$anonfun$async$1$adapted(TaskCreate.scala:121)
at monix.eval.internal.TaskRestartCallback.start(TaskRestartCallback.scala:58)
at monix.eval.internal.TaskRunLoop$.executeAsyncTask(TaskRunLoop.scala:564)
at monix.eval.internal.TaskRunLoop$.startFull(TaskRunLoop.scala:115)
at monix.eval.internal.TaskRunLoop$.$anonfun$restartAsync$1(TaskRunLoop.scala:192)
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Seems that it doesn't properly handle deviations from the protocol and throws an error in case if a received opcode doesn't match to the expected valid set of opcodes.
I've checked the WebSockets RFC and it says that a server must close a connection and return 400 in case of an handshake error - https://tools.ietf.org/html/rfc6455#section-4.2.1
Also, it says that opcodes from 3 to 7 are reserved for the future usage and I didn't find information on how they should be handled exactly. However, there is a sentence: If an unknown
opcode is received, the receiving endpoint MUST _Fail the
WebSocket Connection_., though not sure if it's applicable to them - https://tools.ietf.org/html/rfc6455#section-5.2
Probably at least server could handle such opcodes and print something less scary and more understandable for users.
- 主要言語
- Scala
- スター
- 371
- フォーク
- 63
- 平均マージ
- 7時間 47分
- マージ済み PR(30日)
- 5
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
http4s/blaze のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 30/100
-
support
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
似ている issue
-
enhancement good first issue help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
メンテナーはふだん 1 日以内に返信
-
bug minor
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
propensive/soundness#2418 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
scylladb/scylla-migrator#432 ·
メンテナーはふだん 1 日以内に返信
-
requires-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
apache/datafusion-comet#7479 ·
メンテナーはふだん 2 日以内に返信
-
30-minutes algorithm any-language codewars dart easy elixir hackerrank hacktoberfest haskell help wanted interview-prep julia leetcode lua open-source r scala students zig
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
Huerte/algo-solutions-python#163 ·
メンテナーはふだん 1 日以内に返信