Background
Brakeman version: v8.0.4
Rails version: 8.0.2.1
Ruby version: 3.4.1
Link to Rails application code: sorry, private repo
False Positive
Full warning from Brakeman:
== Warnings ==
Confidence: Medium
Category: Command Injection
Check: Execute
Message: Possible command injection
Code: Open3.capture3("git", "diff", "origin/main", "origin/#{release_branch}".shellescape, "db/fixtures/masters/festivals.csv")
File: app/services/event_release_service/festivals/extract_release_targets.rb
Line: 12
Relevant code:
def self.call(release_branch)
...
diff_output, _error, _status = Open3.capture3('git', 'diff', 'origin/main', "origin/#{release_branch}".shellescape, 'db/fixtures/masters/festivals.csv')
Why might this be a false positive?
Brakeman treats dynamic string segments passed into Open3.capture3 as if they might be executed by a shell. Here, Open3.capture3 is called with multiple separate string arguments. In Ruby, that form uses spawn-style execution: the program is invoked with a discrete argv list and no shell is spawned by default. The interpolated value is therefore passed as a single argument to git (the refspec origin/), not parsed as shell syntax. Characters that would be dangerous in a shell string (spaces, ;, |, `, $(), etc.) do not gain shell metacharacter meaning in this API shape; they are only part of the ref string git receives.
So the finding conflates “string built with interpolation” with “user input concatenated into a shell command line.” The latter is command injection; the former, in multi-argument Open3.capture3, is argument passing to git only. Any abuse is limited to what git diff does with a malformed ref name, not arbitrary command execution via the shell.
Background
Brakeman version: v8.0.4
Rails version: 8.0.2.1
Ruby version: 3.4.1
Link to Rails application code: sorry, private repo
False Positive
Full warning from Brakeman:
Relevant code:
Why might this be a false positive?
Brakeman treats dynamic string segments passed into Open3.capture3 as if they might be executed by a shell. Here, Open3.capture3 is called with multiple separate string arguments. In Ruby, that form uses spawn-style execution: the program is invoked with a discrete argv list and no shell is spawned by default. The interpolated value is therefore passed as a single argument to git (the refspec origin/), not parsed as shell syntax. Characters that would be dangerous in a shell string (spaces, ;, |, `, $(), etc.) do not gain shell metacharacter meaning in this API shape; they are only part of the ref string git receives.
So the finding conflates “string built with interpolation” with “user input concatenated into a shell command line.” The latter is command injection; the former, in multi-argument Open3.capture3, is argument passing to git only. Any abuse is limited to what git diff does with a malformed ref name, not arbitrary command execution via the shell.