CVE-2023-51763
Description
csv_builder.rb in ActiveAdmin (aka Active Admin) before 3.2.0 allows CSV injection.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
ActiveAdmin before 3.2.0 is vulnerable to CSV injection, allowing crafted data to execute arbitrary formulas when exported CSV files are opened by spreadsheet applications.
Root
Cause
CVE-2023-51763 describes a CSV injection vulnerability in the csv_builder.rb file of ActiveAdmin, a popular administration framework for Ruby on Rails. The vulnerability arises because column headers and cell values are not sanitized for characters that spreadsheet applications interpret as formula prefixes. When generating CSV output, the build method directly writes data without escaping leading characters such as =, +, -, @, \t, and \r [1][3]. As a result, any string starting with these characters is output verbatim into the CSV file.
Attack
Vector and Prerequisites
An attacker must first be able to inject or influence values that appear in the exported CSV. In a typical ActiveAdmin context, this could be achieved through user-submitted record attributes (e.g., model fields) that are later included in a CSV download. No special authentication is required beyond normal access to download the CSV; the threat is that a malicious user could plant a payload (such as =CMD(...) or =HYPERLINK(...) in the underlying data. When an administrator or other user opens the exported CSV in a spreadsheet program like Microsoft Excel or LibreOffice Calc, the spreadsheet executes the formula, potentially leading to remote code execution or data exfiltration [2][4].
Impact
Successful exploitation of a CSV injection can lead to arbitrary command execution on the machine of the user opening the file, or to the exfiltration of sensitive data (e.g., via outbound network requests). Because ActiveAdmin is often used to manage backend data, the attacker may be able to craft payloads that leverage formulas like DDE or WEBSERVICE to achieve these effects. The impact is dependent on the spreadsheet application and its security settings, but the potential for remote code execution is severe [2][4].
Mitigation
The vulnerability was addressed in ActiveAdmin version 3.2.0, released on December 24, 2023. The fix introduces a Sanitizer module that prepends a single quote (') to any string value beginning with one of the dangerous characters, causing the spreadsheet to treat the cell content as plain text rather than a formula [1][3]. Users are strongly advised to upgrade to v3.2.0 or later. For versions on the 3-0 stable branch, a backport commit is also available [3]. No known workaround exists for earlier versions, so upgrading is the recommended course of action.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
activeadminRubyGems | < 3.2.0 | 3.2.0 |
Affected products
2- ActiveAdmin/ActiveAdmindescription
Patches
17af735cf657cBackport to 3-0 stable branch protect against CSV Injection (#8161) (#8167)
2 files changed · +71 −2
lib/active_admin/csv_builder.rb+23 −2 modified@@ -51,7 +51,7 @@ def build(controller, csv) csv << bom if bom if column_names - csv << CSV.generate_line(columns.map { |c| encode c.name, options }, **csv_options) + csv << CSV.generate_line(columns.map { |c| sanitize(encode(c.name, options)) }, **csv_options) end controller.send(:in_paginated_batches) do |resource| @@ -70,7 +70,7 @@ def exec_columns(view_context = nil) def build_row(resource, columns, options) columns.map do |column| - encode call_method_or_proc_on(resource, column.data), options + sanitize(encode(call_method_or_proc_on(resource, column.data), options)) end end @@ -86,6 +86,10 @@ def encode(content, options) end end + def sanitize(content) + Sanitizer.sanitize(content) + end + def method_missing(method, *args, &block) if @view_context.respond_to? method @view_context.public_send method, *args, &block @@ -120,4 +124,21 @@ def column_transitive_options @column_transitive_options ||= @options.slice(*COLUMN_TRANSITIVE_OPTIONS) end end + + # Prevents CSV Injection according to https://owasp.org/www-community/attacks/CSV_Injection + module Sanitizer + extend self + + ATTACK_CHARACTERS = ["=", "+", "-", "@", "\t", "\r"].freeze + + def sanitize(value) + return "'#{value}" if require_sanitization?(value) + + value + end + + def require_sanitization?(value) + value.is_a?(String) && value.starts_with?(*ATTACK_CHARACTERS) + end + end end
spec/unit/csv_builder_spec.rb+48 −0 modified@@ -277,4 +277,52 @@ def view_context end end end + + context "csv injection" do + let(:dummy_controller) do + class DummyController + def in_paginated_batches(&block) + Post.all.each(&block) + end + + def view_context + MethodOrProcHelper + end + end + DummyController.new + end + + let(:builder) do + ActiveAdmin::CSVBuilder.new do + column(:id) + column(:title) + end + end + + ["=", "+", "-", "@", "\t", "\r"].each do |char| + it "prepends a single quote when column starts with a #{char} character" do + attack = "#{char}1+2" + + escaped_attack = "'#{attack}" + escaped_attack = "\"#{escaped_attack}\"" if char == "\r" + + post = Post.create!(title: attack) + receiver = [] + builder.build dummy_controller, receiver + line = receiver.last + expect(line).to eq "#{post.id},#{escaped_attack}\n" + end + + it "accounts for the field separator when character #{char} is used to inject a formula" do + attack = "#{char}1+2'\" ;,#{char}1+2" + escaped_attack = "\"'#{attack.gsub('"', '""')}\"" + + post = Post.create!(title: attack) + receiver = [] + builder.build dummy_controller, receiver + line = receiver.last + expect(line).to eq "#{post.id},#{escaped_attack}\n" + end + end + end end
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-xhvv-3jww-c487ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-51763ghsaADVISORY
- github.com/activeadmin/activeadmin/commit/7af735cf657c73734fca1900cd6a5adac4ee706eghsaWEB
- github.com/activeadmin/activeadmin/pull/8167ghsaWEB
- github.com/activeadmin/activeadmin/releases/tag/v3.2.0ghsaWEB
- github.com/activeadmin/activeadmin/security/advisories/GHSA-xhvv-3jww-c487ghsaWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/activeadmin/CVE-2023-51763.ymlghsaWEB
- github.com/activeadmin/activeadmin/commit/697be2b183491beadc8f0b7d8b5bfb44f2387909mitre
- github.com/activeadmin/activeadmin/pull/8161mitre
- jzee-rx.medium.com/cve-2023-51763-csv-injection-in-activeadmin-a-security-research-breakdown-d5b0d3663aa4mitre
News mentions
0No linked articles in our index yet.