Ruby's Time security fix removes ambiguous whitespace matching
CVE-2023-28756 affects parsing of crafted invalid time strings, and the patched parser changes how whitespace is matched around optional seconds.
Rejecting a malformed timestamp can require more work than accepting a valid one. A parser built from a regular expression may revisit different ways of assigning characters to repeated portions of the pattern before it concludes that no match exists. The cost of failure becomes part of the service's input-processing behavior.
Ruby's March 30 Time advisory discloses CVE-2023-28756. Invalid strings containing particular characters can increase the time required to parse a Time value. The project releases time 0.1.1 and 0.2.2 to address the regular-expression denial-of-service issue.
Ruby's readable code is one reason I find it approachable. A short parsing method can nevertheless hide a complicated search inside a regular expression. This fix is a useful example of why input rejection needs an implementation-level explanation, even when the public API remains unchanged.
The release diff identifies the parser
The advisory describes the Time parser broadly. Comparing time 0.2.1 with 0.2.2 locates the relevant change in Time.rfc2822. Its modified expression handles the minute field, optional seconds, and surrounding whitespace.
Previously, whitespace matching after the minutes could be followed by an optional seconds group and another whitespace matcher. When the optional group did not match, adjacent repeated whitespace portions could cover overlapping allocations of the same characters.
The patch removes the whitespace repetition immediately after the minute digits. Whitespace preceding a seconds separator moves inside the optional seconds group. If seconds are absent, that internal matcher is absent too, leaving the later required whitespace matcher to handle the boundary before the zone.
This is an interpretation of the visible expression change, rather than an additional impact claim from the advisory. It explains why a small textual modification can reduce repeated work. The public operation is still parsing an RFC-style date string, but the expression has fewer competing ways to account for whitespace at that boundary.
Optional structure affects rejection cost
Optional syntax introduces more than a successful form that may or may not be present. A backtracking matcher also needs to decide whether an attempted optional match should be abandoned when a later part fails. Repetition beside that optional structure can multiply the paths explored.
In this change, moving the whitespace into the optional seconds group ties it to the syntax that actually needs it. The parser no longer has to consider that whitespace repetition independently when no seconds separator is present.
That mechanism is more informative than saying the patch simply makes parsing faster. Ordinary valid inputs and deliberately malformed inputs can exercise different paths. The advisory concerns crafted invalid strings, so successful timestamp examples alone would not establish the absence of the issue.
The comparison also contains changes to test infrastructure. Those should not be mistaken for additional application-facing vulnerabilities. The security-relevant parser change is identifiable without treating every line in a maintenance diff as part of the same mechanism.
Time parsing includes several different APIs
The patched source documents the methods added when the time library is required. These include RFC-style parsing, HTTP dates, XML Schema date-time parsing, heuristic parsing, and parsing according to a supplied format.
Time.parse is explicitly documented as a heuristic, not a validator. It can infer missing elements from a reference date and may produce an unexpected result when input does not strictly match an intended format. That API contract is separate from the performance defect addressed by this advisory.
A protocol accepting an RFC-style date should identify that format directly. The following ordinary input demonstrates the method whose expression changed, without reproducing a denial-of-service input.
require "time"
timestamp = Time.rfc2822("Thu, 30 Mar 2023 11:00:00 +0000")
puts timestamp.utc
The source documents ArgumentError for an input that does not comply with the method's expected form or cannot be represented as a Time. Handling that error decides what the application does after rejection. Updating the library addresses the cost incurred before that decision can happen.
Choosing a narrower parser is useful API design, but it is not a substitute for this patch. The modified code is itself a format-specific parser. Precision about accepted syntax and bounded processing of invalid syntax remain distinct properties. I prefer seeing those properties discussed separately, since a familiar method name alone says little about the work required to reject an input.
Patched versions depend on the Ruby series
The advisory identifies time 0.1.0 and 0.2.1 as affected gem versions. It also identifies Ruby 2.7.7 and lower in its affected-version list. The separately distributed time gem requires Ruby 3.0 or later.
For Ruby 3.0, the project recommends time 0.1.1 to retain compatibility with that series. For Ruby 3.1 and 3.2, it recommends time 0.2.2. Ruby 2.7 users need the latest Ruby version rather than an attempted installation of a gem that does not support that interpreter.
For the supported newer series, the advisory documents updating the gem directly. The command below is the published direct-update instruction.
gem update time
Its Bundler recommendation for the 0.2 line is an explicit dependency constraint. This lets the application's dependency declaration require the patched release.
gem "time", ">= 0.2.2"
That line is not the compatibility recommendation for Ruby 3.0. Keeping the series-specific instructions visible prevents a broadly copied remediation example from excluding the interpreter it was supposed to protect.
The relevant dependency is the time implementation loaded by the application. A project using Bundler needs its declared requirements and resolved version to permit the fixed release. The security recommendation is about that actual library version, not merely the presence of a newer gem somewhere on the machine.
The disclosed impact stays specific
The advisory credits ooooooo_q for discovering the issue. Its stated impact is increased parsing time for specially formed invalid strings. It does not describe data disclosure or code execution, and it does not provide a universal duration for a malicious parse.
The failure mechanism and the version guidance are sufficient to explain the maintenance decision. An application that parses externally supplied time strings can perform expensive work before it rejects them. The patched expression changes that work, while the series-specific gem releases make the correction available within the compatibility limits documented by the Ruby project.