In the world of web development, Ruby on Rails has earned its spot thanks to its powerful features and vast ecosystem. But even strong frameworks can have weak spots. One recent vulnerability, recorded as CVE-2023-22796, exposed applications to a sneaky denial-of-service (DoS) attack through something as simple as the underscore function in ActiveSupport. If you’re using Rails <6.1.7.1 or <7..4.1, read on: this may impact your systems.

Let's break down what happened, see some real-world examples, and talk about how to stay safe.

What is CVE-2023-22796?

ActiveSupport is a core utility library for Ruby on Rails. The underscore method is used to convert "CamelCase" strings into "snake_case" strings. Think turning "FooBar" into "foo_bar". It seems harmless, but under-the-hood, it's powered by a regular expression that wasn’t as robust as it should have been.

The vulnerability comes down to *catastrophic backtracking* in regular expressions. In simpler terms, if you feed a specially-crafted evil string to underscore, Ruby can spend tons of CPU time and memory trying to process it, hanging your server in the process. That's a denial-of-service (DoS).

The Vulnerable Code

Here’s the vulnerable code (from inflections.rb), slightly simplified:

def underscore(camel_cased_word)
  # ...other processing...
  word.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') # regular expression causes the issue
      .gsub(/([a-z\d])([A-Z])/, '\1_\2')
      .downcase
end

This code works just fine for most strings. But if you craft an input that makes the regular expression engine do lots of useless work (catastrophic backtracking), things can get ugly fast.

Here's a Ruby snippet that demonstrates the issue, using a dangerous input

require "active_support/inflector"

# This string is designed to trigger catastrophic backtracking
evil_string = "A" + ("aAaA" * 100_000) + "!"

begin
  puts "Processing…"
  ActiveSupport::Inflector.underscore(evil_string)
rescue => e
  puts "Exception: #{e}"
end

You’ll notice this code eats up a *lot* of CPU and memory before either succeeding (eventually) or the process is killed. An attacker could use this to hang a Rails app just by passing similar input.

Attack Scenarios

Someone could use this flaw by submitting a form with a malicious string in any field processed by underscore — such as user names, categories, or other model fields. APIs, background jobs, or web UIs calling underscore are all potentially at risk. A single request could hog CPU resources, making your app unresponsive for others and risking a forced crash.

ActiveSupport 7..4.1 and later

Patch summary:  
They modified the regular expression to be more strict and avoid patterns that can cause exponential backtracking.

See the patch:  
- GitHub commit - Rails: Fix CVE-2023-22796
- Rails Security Advisory

Update your Gemfile to use a safe version

gem 'activesupport', '>= 6.1.7.1' # or 7..4.1

Then run

bundle update activesupport

Further Reading

- CVE Details: CVE-2023-22796
- Original Rails Security Release

TL;DR

CVE-2023-22796 is a vulnerability in Rails' ActiveSupport, allowing regular expression-based DoS attacks via the underscore method. Anyone using Rails below 6.1.7.1 or 7..4.1 should patch immediately. Until then, your app could be brought down with a single smartly-crafted string.

Timeline

Published on: 02/09/2023 20:15:00 UTC
Last modified on: 03/14/2023 08:15:00 UTC