From 580838df16a4abeb7bd69763db676cb6549f146a Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Fri, 28 Aug 2026 03:14:00 +0300 Subject: [PATCH 1/2] Reject repeated activation of the same extension session --- lib/websocket/extensions.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/websocket/extensions.rb b/lib/websocket/extensions.rb index 14ca7ab..0b246d2 100644 --- a/lib/websocket/extensions.rb +++ b/lib/websocket/extensions.rb @@ -75,6 +75,7 @@ def generate_offer def activate(header) responses = Parser.parse_header(header) @sessions = [] + activated = {} responses.each_offer do |name, params| unless record = @index[name] @@ -83,6 +84,11 @@ def activate(header) ext, session = *record + if activated[name] + raise ExtensionError, %Q{Server sent multiple responses for extension "#{ name }"} + end + activated[name] = true + if reserved = reserved?(ext) raise ExtensionError, %Q{Server sent two extension responses that use the RSV#{ reserved[0] }} + %Q{bit: "#{ reserved[1] }" and "#{ ext.name }"} From 3a743d07a5c78ab0b37f11439690732ada3fe169 Mon Sep 17 00:00:00 2001 From: Oskar Eichler <62393985+OskarEichler@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:43:31 +0300 Subject: [PATCH 2/2] Add extension lifecycle regression coverage --- spec/websocket/extensions_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/websocket/extensions_spec.rb b/spec/websocket/extensions_spec.rb index ccb305d..d566778 100644 --- a/spec/websocket/extensions_spec.rb +++ b/spec/websocket/extensions_spec.rb @@ -120,6 +120,13 @@ expect { @extensions.activate("tar") }.not_to raise_error end + it "rejects duplicate responses for an extension without reserved bits" do + allow(@ext).to receive(:rsv1).and_return(false) + expect(@session).to receive(:activate).with({}).exactly(1).and_return(true) + + expect { @extensions.activate("deflate, deflate") }.to raise_error(ExtensionError) + end + it "raises if two extensions conflict on RSV bits" do expect { @extensions.activate("deflate, tar") }.to raise_error(ExtensionError) end