CVE-2023-22794
High · 8.8CVSS
8.8
EPSS
2.2%
Published
Feb 9, 2023
CISA due date
—
Cloudanix analysis
Some Rails applications can be tricked into changing database queries if unsafe user input is included in query comments, potentially exposing or altering stored data.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Web Framework
- Class
- SQL Injection
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
CVE-2023-22794 is a SQL injection flaw in Ruby on Rails Active Record query annotation/comment handling. When attacker-controlled input is passed into APIs that add SQL comments to generated queries, insufficient sanitization can allow comment termination and injection of additional SQL fragments. Impact depends on database permissions and application query patterns, but can include unauthorized data reads, modification, deletion, authentication bypass through query manipulation, or database error disclosure. The issue is not in every Rails route by default; exploitation requires an application to pass untrusted input into the vulnerable Active Record comment/annotation path.
Why it matters to the business
A vulnerable Rails application may expose sensitive business data or allow unauthorized changes to data if user input reaches the affected Active Record SQL comment functionality. Because Rails is widely used for web applications and public exploit information is available, affected internet-facing applications should be prioritized even though this issue is not currently in CISA KEV and has a relatively low EPSS score. Successful exploitation can lead to data breach response costs, regulatory exposure, service disruption from corrupted records, and loss of customer trust.
How an attack unfolds
An attacker first identifies a Rails endpoint or feature where a request parameter is incorporated into Active Record query annotations or SQL comments. They submit crafted input containing SQL comment-breakout sequences and database-specific SQL syntax so that the application-generated query is altered when sent to the database. If the database accepts the modified query, the attacker iterates payloads to enumerate schema details, extract records, change application data, or trigger error messages that reveal useful information. Exploitation is constrained by whether the vulnerable API is reachable with attacker-controlled data, the database adapter in use, SQL permissions granted to the application user, and whether application or WAF controls block suspicious payloads. The supplied threat-actor field appears to reference an unrelated HTTP/2 Rapid Reset issue rather than a named actor known to exploit this Rails flaw.
How to fix it
Upgrade Rails to a version containing the upstream fix. For the Git-sourced rails/rails package, apply or upgrade past commit 28bb76d3efc39b2ef663dfe2346f7c2621343cd6. For packaged Rails deployments, use vendor-supported releases that include the fix, commonly Rails 6.1.7.1 or 7.0.4.1 or later, and verify against the official Rails advisory for the maintained branch in use. Rebuild and redeploy applications after updating dependencies, refresh lockfiles, and restart application processes. As an interim mitigation, ensure no untrusted request data is passed to Active Record query annotation/comment APIs such as annotate or optimizer hint/comment-like helpers; replace dynamic annotations with static strings, strict allowlists, or remove them entirely. Keep database accounts least-privileged so application credentials cannot perform unnecessary DDL, administrative operations, or broad writes.
How to confirm the fix worked
Confirm dependency resolution shows Rails/Active Record at a fixed release or, for Git-based installs, at or after commit 28bb76d3efc39b2ef663dfe2346f7c2621343cd6. Review Gemfile.lock, bundler-audit, Dependabot, osv-scanner, Snyk, or similar SCA results to ensure CVE-2023-22794 is no longer reported. Search application code for Active Record annotation/comment usage and verify attacker-controlled values are not passed into those APIs. In a non-production test environment, send safe validation strings containing SQL comment delimiters such as */ and confirm they are escaped, rejected, or do not alter generated SQL. Enable SQL logging during testing and inspect generated queries to ensure annotation content remains inside comments and cannot terminate the comment block.
Typical attack path
- Reconnoiter the Rails application for endpoints whose parameters affect query metadata, annotations, reporting, search, filtering, debugging, or administrative query labels.
- Send benign probes containing SQL comment delimiters and metacharacters to observe database errors, response changes, timing differences, or log artifacts.
- Craft a payload that terminates the intended SQL comment and appends attacker-controlled SQL syntax compatible with the backend database.
- Use iterative SQL injection techniques to confirm control over the query, enumerate database structure, and identify high-value tables or records.
- Extract, modify, or delete data within the privileges of the application database account, or use database functions to support further compromise if permissions allow.
- Cover tracks by minimizing noisy errors, using time-based or boolean techniques, and blending payloads into normal web traffic.
How to detect it
To determine whether exploitation already occurred, correlate web access logs, application logs, Rails exception logs, WAF alerts, and database query/error logs. Focus on endpoints that accept parameters later used in query annotations, comments, reporting labels, search filters, exports, or admin/debug features. Look for SQL comment-breakout sequences such as */ followed by SQL keywords, URL-encoded variants, unexpected database syntax errors, and bursts of 4xx/5xx responses during probing. Database logs may show malformed comments, stacked-query attempts, UNION/select probes, sleep/time-delay functions, or unusually broad SELECT/UPDATE/DELETE activity by the application database user. Rails logs may contain ActiveRecord::StatementInvalid, adapter-specific SQL errors, or request parameters with encoded comment delimiters. If suspicious activity is found, preserve relevant request bodies, query logs, database audit records, and application deployments for forensic review, then assess whether sensitive records were accessed or modified.
- */
- %2A%2F
- %2a%2f
- */--
- %2A%2F--
- */#
- */;
- ActiveRecord::StatementInvalid
- PG::SyntaxError
- PG::Error
- Mysql2::Error
- SQLite3::SQLException
- You have an error in your SQL syntax
- unterminated /* comment
- unterminated comment
- syntax error at or near
- UNION SELECT
- union select
- SLEEP(
- pg_sleep(
- benchmark(
- information_schema
- sqlite_master
- 28bb76d3efc39b2ef663dfe2346f7c2621343cd6
What your security team should do
- Inventory Rails applications and identify those using affected Rails/Active Record versions, prioritizing internet-facing and data-sensitive applications.
- Patch or upgrade to a fixed Rails version, or apply the upstream Git commit 28bb76d3efc39b2ef663dfe2346f7c2621343cd6 where source-based dependency management is used.
- Review code for dynamic use of Active Record query annotations/comments and remove or strictly sanitize any user-controlled values.
- Run SCA tooling in CI/CD and fail builds that resolve to vulnerable Rails versions.
- Harden database permissions for application accounts to reduce blast radius from SQL injection.
- Increase logging around web requests, application exceptions, and database errors while patching is underway.
- Hunt historical logs for SQL comment-breakout payloads, unusual database errors, and suspicious requests targeting endpoints that influence query annotations.
- Add WAF or reverse-proxy detection for SQL comment termination and stacked-query patterns as compensating control, while avoiding reliance on WAF rules as the primary fix.
The record
A vulnerability in ActiveRecord <6.0.6.1, v6.1.7.1 and v7.0.4.1 related to the sanitization of comments. If malicious user input is passed to either the `annotate` query method, the `optimizer_hints` query method, or through the QueryLogs interface which automatically adds annotations, it may be sent to the database withinsufficient sanitization and be able to inject SQL outside of the comment.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| RubyGems | activerecord | 6.0.0 | 6.0.6.1 |
| RubyGems | activerecord | 6.1.0 | 6.1.7.1 |
| RubyGems | activerecord | 7.0.0 | 7.0.4.1 |
| Debian:11 | rails | 0 | 2:6.0.3.7+dfsg-2+deb11u1 |
| Debian:12 | rails | 0 | 2:6.1.7.3+dfsg-1 |
| Debian:13 | rails | 0 | 2:6.1.7.3+dfsg-1 |
| Red Hat:satellite:6.14::el8 | foreman | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-cli | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-debug | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-dynflow-sidekiq | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-ec2 | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-journald | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-libvirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-openstack | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-ovirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-postgresql | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-redis | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-service | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-telemetry | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | foreman-vmware | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite:6.14::el8 | puppet-agent | 0 | 0:7.26.0-3.el8sat |
| Red Hat:satellite:6.14::el8 | puppetserver | 0 | 0:7.11.0-1.el8sat |
| Red Hat:satellite:6.14::el8 | python-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite:6.14::el8 | python39-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite:6.14::el8 | rubygem-actionpack | 0 | 0:6.1.7.3-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-activerecord | 0 | 0:6.1.7.3-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-activesupport | 0 | 0:6.1.7.3-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-git | 0 | 0:1.18.0-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-globalid | 0 | 0:1.1.0-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-kubeclient | 0 | 0:4.10.1-1.el8sat |
| Red Hat:satellite:6.14::el8 | rubygem-rack | 0 | 0:2.2.7-1.el8sat |
| Red Hat:satellite:6.14::el8 | yggdrasil-worker-forwarder | 0 | 0:0.0.3-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-cli | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-debug | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-dynflow-sidekiq | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-ec2 | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-journald | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-libvirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-openstack | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-ovirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-postgresql | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-redis | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-service | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-telemetry | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | foreman-vmware | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | puppet-agent | 0 | 0:7.26.0-3.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | puppetserver | 0 | 0:7.11.0-1.el8sat |
| Red Hat:satellite_capsule:6.14::el8 | python-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-django | 0 | 0:3.2.21-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-future | 0 | 0:0.18.3-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-gitpython | 0 | 0:3.1.32-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-pulp-ansible | 0 | 1:0.16.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-requests | 0 | 0:2.31.0-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | python39-sqlparse | 0 | 0:0.4.4-1.el8pc |
| Red Hat:satellite_capsule:6.14::el8 | rubygem-rack | 0 | 0:2.2.7-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-cli | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-debug | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-dynflow-sidekiq | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-ec2 | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-journald | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-libvirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-openstack | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-ovirt | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-postgresql | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-redis | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-service | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-telemetry | 0 | 0:3.7.0.9-1.el8sat |
| Red Hat:satellite_utils:6.14::el8 | foreman-vmware | 0 | 0:3.7.0.9-1.el8sat |
| Ubuntu:20.04:LTS | rails | 0 | No fix |
| Ubuntu:22.04:LTS | rails | 0 | No fix |
| Ubuntu:24.04:LTS | rails | 0 | No fix |
| Ubuntu:24.10 | rails | 0 | No fix |
| Ubuntu:25.04 | rails | 0 | No fix |
| Ubuntu:25.10 | rails | 0 | No fix |
| Ubuntu:Pro:16.04:LTS | rails | 0 | No fix |
| Ubuntu:Pro:18.04:LTS | rails | 0 | No fix |
| Ubuntu:Pro:20.04:LTS | rails | 0 | No fix |
| Ubuntu:Pro:22.04:LTS | rails | 0 | No fix |
| gem | activerecord | 6.0.0 | 6.0.6.1 |
| gem | activerecord | 6.1.0 | 6.1.7.1 |
| gem | activerecord | 7.0.0 | 7.0.4.1 |
| openSUSE:Tumbleweed | rubygem-activerecord-7.0 | 0 | 7.0.4.1-1.1 |
| openSUSE:Tumbleweed | rubygem-activerecord-7.0 | 0 | 7.0.8.4-1.1 |
| openSUSE:Tumbleweed | rubygem-activerecord-7.0 | 0 | 7.0.8.6-1.3 |
Related vulnerabilities
- CVE-2025-55193 Active Record connects classes to relational database tables. Also affects activerecord
- CVE-2022-44566 A denial of service vulnerability present in ActiveRecord's PostgreSQL adapter <7.0.4.1… Also affects activerecord
- CVE-2022-32224 A possible escalation to RCE vulnerability exists when using YAML serialized columns in… Also affects activerecord
- CVE-2023-28120 There is a vulnerability in ActiveSupport if the new bytesplice method is called on a… Also affects rails
- CVE-2023-23913 There is a potential DOM based cross-site scripting issue in rails-ujs which leverages… Also affects rails
- CVE-2023-28362 The redirect_to method in Rails allows provided values to contain characters which are… Also affects rails
- CVE-2023-38037 ActiveSupport::EncryptedFile writes contents that will be encrypted to a temporary file. Also affects rails
- CVE-2024-54133 Action Pack is a framework for handling and responding to web requests. Also affects rails