Hi,

At first glance this looks good.

The 2 not-affected are not reported in the security tracker, maybe you can do it directly, with your rationale (streaming proxy module not present).

Did you try to manually run a rails app and see if everything's good? We have some notes at https://lts-team.pages.debian.net/wiki/TestSuites/rails.html , redmine can be a good candidate, when available for the target rails version.

Cheers!
Sylvain Beucler
Debian LTS Team

On 05/10/2026 03:52, Simon Quigley wrote:
Bookworm rails is 2:6.1.7.10+dfsg-1~deb12u2. I put the seven no-dsa CVEs whose code is in Rails 6.1, and CVE-2026-66066 for applications that set the variant processor to :vips, into one update, 2:6.1.7.10+dfsg-1~deb12u3. The commits are pushed to Salsa and a debdiff is attached.

These are the ones I fixed:

- CVE-2026-66066: the vips processor calls vips_block_untrusted_set before it opens an upload. ruby-vips 2.1.4 does not bind that function, so the patch attaches it. BMP variants then raise Vips::Error. The MiniMagick default is unchanged. - CVE-2026-33168: a blank HTML attribute name skipped escaping. Blank names are now skipped. - CVE-2026-33169: delimiting a long digit string was quadratic. The default path walks the digits. 1,234,567 still looks the same. - CVE-2026-33170: formatting an unsafe SafeBuffer with % marked the result safe. It stays unsafe. - CVE-2026-33173: a direct upload could set analyzed and identified and skip content-type detection. Those keys are dropped. Rails 6.1 has no composed flag. - CVE-2026-33176: number helpers expanded scientific notation through BigDecimal. number_to_currency("1E1000") stays "$1E1000". - CVE-2026-33195: a disk key with ../ could leave the storage root. That now raises InvalidKeyError. - CVE-2026-33202: delete_prefixed passed the prefix to Dir.glob. Glob metacharacters are escaped.

CVE-2026-66066 closes #1143080. Each of the other seven closes #1132035. That bug was closed by 2:7.2.3.1+dfsg-1.

CVE-2026-33174 and CVE-2026-33658 stay out of this update. I asked the Security Team to mark those two not-affected. There is no 6.1 commit for either of them.

CVE-2026-33174 is the proxy holding a whole Range in one string. On 7.2, streaming.rb calls download_chunk, which does file.read(range.size). bytes=0- on a large file is that allocation. Bookworm's blob proxy and representation proxy do not have that file, and they do not read the Range header. ActiveStorage::BaseController#stream writes the file out in 5MB chunks. download_chunk exists, but outside the tests the only caller reads the first 4KB. The disk service URL does honor Range, through Rack::Files in ruby-rack 2.2.22, in 8KB reads. That is not this bug.

CVE-2026-33658 is the same proxy appending every range in the header onto one buffer. Bookworm's proxy never calls Rack::Utils.get_byte_ranges. Rack::Files on the disk URL does accept several ranges, and it walks them in 8KB reads instead of building one string. There is no streaming_max_ranges method to patch.

CVE-2026-66066 is in this update. The Bookworm default stays :mini_magick, and the engine still loads image_analyzer.rb only. Setting the variant processor to :vips used to leave libvips's unfuzzed loaders on, because ruby-vips 2.1.4 never calls vips_block_untrusted_set and image_processing 1.10.3 never calls block_untrusted. The patch attaches that symbol from libvips 8.14.1 and calls it when the vips processor runs. The 7.2 file calls Vips.block_untrusted and raises at boot on 2.1.4, so this is not that file.

I built this in a Bookworm schroot. The packaged test suite was 344 runs and 0 failures on each of five runs, with 24 and 26 skips on the first two. autopkgtest newapp and gem2deb-test-runner both passed. That runner only executes Active Job, so on bookworm-testing I ran the same behavioral script as Trixie, first on 2:6.1.7.10+dfsg-1~deb12u2 and then on this package.

On the archive package the seven were VULNERABLE in the same way as Trixie. A blank attribute name emitted the onerror value. Delimiting 50,000 ones took 6.2 seconds. An unsafe SafeBuffer became html_safe after %. number_to_currency("1E1000") expanded to about 1,300 characters. path_for reached /etc/passwd. delete_prefixed with a [1] prefix deleted the plain sibling and left the bracket key. Direct upload metadata was not filtered. CVE-2026-33174 and CVE-2026-33658 were NOT_AFFECTED: there is no streaming proxy. With the variant processor set to :vips, before the 66066 patch, an SVG and a BMP both opened.

On this package those seven reported FIXED. 1,234,567 and $1,234.50 were unchanged, the Indian delimiter pattern still worked, a blank attribute value was kept, a safe buffer stayed safe, and avatars/123/photo stayed inside the root. Traversal, blank, and null-byte keys were rejected. The bracket key was the only one the glob prefix deleted. analyzed and identified were dropped and the caption stayed. 50,000 ones took 0.005 seconds. CVE-2026-33174 and CVE-2026-33658 were NOT_AFFECTED again. After the 66066 patch I ran the variants through ImageProcessingTransformer#transform. PNG, JPEG, WebP, TIFF, and GIF each resized to 8x6 as PNG, JPEG, and WebP. SVG, PPM, BMP, ICO, PSD, and PDF were blocked. Saving a PNG variant as BMP was blocked. Twenty-five PNG variants in one process still resized. The MiniMagick default still resized a PNG and left svgload available.

Salsa pipeline: https://salsa.debian.org/ruby-team/rails/-/ pipelines/1183706

Debusine work request: https://debusine.debian.net/debian/developers/ work-request/1418454/

Feedback is welcome. If nothing showstopping is raised, I plan to upload this on the morning of Thursday, October 8th, 2026, or whenever the Trixie DSA is issued for this set of CVEs, whatever comes later.

Best regards,
Simon Quigley
[email protected]

Reply via email to