2.2 KiB
Hanami — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in Hanami's slice registration system. The filter_slice_names method uses Array#& (array intersection) which is O(N×M) instead of converting to a Set first for O(N+M). Fires on every application boot and code reload. Patch ready for upstream review.
The Defects
hanami-0001 (PATCHED — HIGH): lib/hanami/slice_registrar.rb
# filter_slice_names uses Array#& intersection:
slice_names & configured_slices # O(N×M) array intersection per boot/reload
Array#& performs an O(N×M) intersection operation — for each element of the left array, it scans the right array. Called on every Hanami application boot and code reload. For N slice names and M configured slices: O(N × M) per registration.
Complexity Proof
For N=160 slice names and M configured slices:
Array#&intersection: O(N×M)- Fixed:
.to_seton right side → O(N+M) - At N=M=160: 25,600 comparisons vs 320 operations
- Measured ratio: 160×.
Impact
All Hanami 2.x applications. The slice registrar runs on every application boot and in development on every code reload. Applications with many slices (domain slices, feature slices, engine slices) maximize N×M. Hanami 2.x is the current major release; this defect affects the core boot path.
The Fix
Convert the right-hand side to a Set before intersection:
# Before
slice_names & configured_slices # O(N×M) Array#& intersection
# After
# CWE-407 fix: Set intersection for O(N+M) instead of O(N×M) Array#& scan.
configured_set = configured_slices.to_set
slice_names.select { |name| configured_set.include?(name) }
Patch
defects/hanami/patch/hanami-0001-slice-registrar-set.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your slice registration and boot test suite.
- Assess CVE eligibility — fires on every application boot and code reload.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.