Use of Kernel.open or IO.read with user-controlled input¶
ID: rb/kernel-open
Kind: path-problem
Severity: error
Precision: high
Tags:
- correctness
- security
- external/cwe/cwe-078
- external/cwe/cwe-088
- external/cwe/cwe-073
Query suites:
- ruby-code-scanning.qls
- ruby-security-extended.qls
- ruby-security-and-quality.qls
Click to see the query in the CodeQL repository
If Kernel.open is given a file name that starts with a | character, it will execute the remaining string as a shell command. If a malicious user can control the file name, they can execute arbitrary code. The same vulnerability applies to IO.read.
Recommendation¶
Use File.open instead of Kernel.open, as the former does not have this vulnerability. Similarly, use File.read instead of IO.read.
Example¶
The following example shows code that calls Kernel.open on a user-supplied file path.
class UsersController < ActionController::Base
def create
filename = params[:filename]
open(filename) # BAD
end
end
Instead, File.open should be used, as in the following example.
class UsersController < ActionController::Base
def create
filename = params[:filename]
File.open(filename)
end
end
References¶
OWASP: Command Injection.
Example CVE: Command Injection in RDoc.
Common Weakness Enumeration: CWE-78.
Common Weakness Enumeration: CWE-88.
Common Weakness Enumeration: CWE-73.