java-topology/whitepaper/outreach/sinatra.md

2.5 KiB
Raw Blame History

Sinatra — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

Two O(n²) defects in Sinatra's request processing pipeline. Both use list/array scans on per-request hot paths — one for charset detection, one for content-type matching in provides(). Patches ready for upstream review.

The Defects

sinatra-0001 (PATCHED — HIGH): sinatra/base.rb:1002

# add_charset: array
# Per content_type() response call:
add_charset.all? { |p| !(p === mime_type) }  # O(K) scan per response

add_charset is an array. The all? block performs an O(K) scan over K charset patterns on every content_type() call. For R requests and K charset entries: O(R × K) total.

sinatra-0002 (PATCHED — MEDIUM): sinatra/base.rb:1770

# types: array
# Per request in provides() condition:
types.include?(response_content_type)  # O(T) scan per request

types is an array. O(T) scan per request in the provides() route condition. For R requests and T types: O(R × T) total.

Complexity Proof

sinatra-0001: For K=8 charset entries per request:

  • Each content_type() call: O(K) scan
  • Fixed: freeze a Set at load time, O(1) per call
  • Measured ratio: 8×.

sinatra-0002: For T=34 content types:

  • Per request: O(T) vs O(1) set lookup
  • Measured ratio: 34×.

Impact

sinatra-0001 affects every Sinatra application that sets content types — virtually all applications. The charset check runs on every response.

sinatra-0002 affects every route using provides() content negotiation, which is a core Sinatra routing feature for REST APIs. Both defects scale linearly with request rate, making them amplified under load.

The Fix

sinatra-0001: Freeze add_charset as a Set:

# Before
add_charset.all? { |p| !(p === mime_type) }

# After
# CWE-407 fix: freeze Set at load time for O(1) member? instead of O(K) array scan.
ADD_CHARSET_SET = Set.new(add_charset).freeze
!ADD_CHARSET_SET.any? { |p| p === mime_type }

sinatra-0002: Convert types to a Set before the provides() check.

Patch

defects/sinatra/patch/sinatra-0001-0002-set-charset-types.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your request handling test suite.
  3. Assess CVE eligibility — both defects fire on every request.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.