rack-proxy 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c85038309db55ace1d7ad2de733dc4a539859cf585c2ffb69b73c13a914f1d47
4
- data.tar.gz: e0328851b0d2a9698b05f356bbb0322c6f3cf4c760b10d93a91194df0849ce44
3
+ metadata.gz: 3c875bfa1e0a111ffd460f491dd469b647b8eec3aeed9fe6fab60db8b7d40f27
4
+ data.tar.gz: cdecda577e3d8f9a5216822792f4e406b58168e82e151f9c876dbfeb1a84f66d
5
5
  SHA512:
6
- metadata.gz: 7bba2a24c71a1521a3d9f9d42d7bffd56b8545f05a8f060fb7236c76d0d5dccba4099015eb25f69e5d98d79b937a4e6d8b26fac5e69345a814222bc65cf3f3d9
7
- data.tar.gz: 34502c66d9801a04d95849773d3dc8c43aa24629db6cb780bb06834054ffc41588ddd1610ec39e33f6b7c64b163311633a47bc988b48eacd7d3e0578bda2568f
6
+ metadata.gz: d5c20ab2119c472da460237bc3b731d09023e7805fe6a7f3a122209b3ce8a694ca1d1f5f6c328694b0b440628f08854507b2618e506ff35343fc6cc189cce52e
7
+ data.tar.gz: 745e5f847a9514d1524d11e272c4866576530c3734d106ef7818de84d9718d38ac5ffef664d86c8fe9e468dda19868ce2250bf847dc4e71e0124ea604e69cf08
data/CHANGELOG.md CHANGED
@@ -8,6 +8,21 @@ follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
9
  Nothing yet.
10
10
 
11
+ ## [1.0.3] - 2026-09-25
12
+
13
+ ### Security
14
+
15
+ - Reject backend responses carrying both `Transfer-Encoding` and
16
+ `Content-Length` with `502` in streaming and non-streaming mode. This prevents
17
+ an attacker-controlled length from framing a dechunked downstream response
18
+ (GHSA-42qh-8mx8-7wqm). Rejected streaming responses close the backend connection.
19
+ - Strip response headers named by all backend `Connection` fields, in addition
20
+ to the standard hop-by-hop headers.
21
+
22
+ This is a targeted security backport for 1.x; successful response status types,
23
+ header representations, request framing, and retry behavior remain unchanged.
24
+ Versions 2.0.0 and later already reject the ambiguous response framing.
25
+
11
26
  ## [1.0.2] - 2026-09-01
12
27
 
13
28
  Housekeeping — no library behavior changes. **No action is needed by users:**
@@ -195,7 +210,8 @@ or a compatible fix. See the README's "Upgrading" section for migration steps.
195
210
 
196
211
  Older releases (≤ 0.7.8) predate this changelog; see the git history and tags.
197
212
 
198
- [Unreleased]: https://github.com/ncr/rack-proxy/compare/v1.0.2...HEAD
213
+ [Unreleased]: https://github.com/ncr/rack-proxy/compare/v1.0.3...HEAD
214
+ [1.0.3]: https://github.com/ncr/rack-proxy/compare/v1.0.2...v1.0.3
199
215
  [1.0.2]: https://github.com/ncr/rack-proxy/compare/v1.0.1...v1.0.2
200
216
  [1.0.1]: https://github.com/ncr/rack-proxy/compare/v1.0.0...v1.0.1
201
217
  [1.0.0]: https://github.com/ncr/rack-proxy/compare/v0.8.3...v1.0.0
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class Proxy
5
- VERSION = "1.0.2"
5
+ VERSION = "1.0.3"
6
6
  end
7
7
  end
data/lib/rack/proxy.rb CHANGED
@@ -278,6 +278,13 @@ module Rack
278
278
 
279
279
  code = target_response.code
280
280
  headers = self.class.normalize_headers(target_response.respond_to?(:headers) ? target_response.headers : target_response.to_hash)
281
+ # Net::HTTP dechunks the body but retains the backend's Content-Length.
282
+ # Reject ambiguous framing before removing any hop-by-hop headers so
283
+ # that stale length can never frame the downstream response.
284
+ if headers.key?("Transfer-Encoding") && headers.key?("Content-Length")
285
+ target_response.close if target_response.respond_to?(:close)
286
+ return [502, {}, []]
287
+ end
281
288
  body = target_response.body || []
282
289
  body = [body] unless body.respond_to?(:each)
283
290
  rescue URI::InvalidURIError
@@ -293,7 +300,10 @@ module Rack
293
300
  # Remove hop-by-hop header fields from the response. Use #delete (not
294
301
  # #reject!) so the returned HeaderHash's case-insensitive index stays
295
302
  # consistent on Rack 2 for any downstream middleware.
296
- headers.keys.each { |k| headers.delete(k) if HOP_BY_HOP_HEADERS[k.downcase] }
303
+ connection_named = headers["Connection"].to_s.downcase.split(/[,\n]/).map(&:strip)
304
+ headers.keys.each do |k|
305
+ headers.delete(k) if HOP_BY_HOP_HEADERS[k.downcase] || connection_named.include?(k.downcase)
306
+ end
297
307
 
298
308
  return [502, {}, []] if response_too_large?(target_response, headers, body)
299
309
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacek Becela
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-01 00:00:00.000000000 Z
11
+ date: 2026-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack