mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Enhanced RDoc concerning command injection (#5537)
Clarifies security vulnerabilities for commands. Treats: Kernel.system Kernel.` (backtick) IO.popen IO.read IO.write IO.binread IO.binwrite IO.readlines IO.foreach
This commit is contained in:
parent
542a38f619
commit
e9a2b30744
Notes:
git
2022-02-18 21:46:25 +09:00
Merged-By: BurdetteLamar <BurdetteLamar@Yahoo.com>
4 changed files with 79 additions and 26 deletions
29
doc/command_injection.rdoc
Normal file
29
doc/command_injection.rdoc
Normal file
|
@ -0,0 +1,29 @@
|
|||
== Command Injection
|
||||
|
||||
Some Ruby core methods accept string data
|
||||
that includes text to be executed as a system command.
|
||||
|
||||
They should not be called with unknown or unsanitized commands.
|
||||
|
||||
These methods include:
|
||||
|
||||
- Kernel.system
|
||||
- {`command` (backtick method)}[rdoc-ref:Kernel#`]
|
||||
(also called by the expression <tt>%x[command]</tt>).
|
||||
- IO.popen(command).
|
||||
- IO.read(command).
|
||||
- IO.write(command).
|
||||
- IO.binread(command).
|
||||
- IO.binwrite(command).
|
||||
- IO.readlines(command).
|
||||
- IO.foreach(command).
|
||||
|
||||
Note that some of these methods do not execute commands when called
|
||||
from subclass \File:
|
||||
|
||||
- File.read(path).
|
||||
- File.write(path).
|
||||
- File.binread(path).
|
||||
- File.binwrite(path).
|
||||
- File.readlines(path).
|
||||
- File.foreach(path).
|
71
io.c
71
io.c
|
@ -7374,6 +7374,9 @@ static VALUE popen_finish(VALUE port, VALUE klass);
|
|||
* Executes the given command +cmd+ as a subprocess
|
||||
* whose $stdin and $stdout are connected to a new stream +io+.
|
||||
*
|
||||
* This method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
* If no block is given, returns the new stream,
|
||||
* which depending on given +mode+ may be open for reading, writing, or both.
|
||||
* The stream should be explicitly closed (eventually) to avoid resource leaks.
|
||||
|
@ -9813,10 +9816,15 @@ argf_readlines(int argc, VALUE *argv, VALUE argf)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* `cmd` -> string
|
||||
* `command` -> string
|
||||
*
|
||||
* Returns the <tt>$stdout</tt> output fromm running +cmd+ in a subshell;
|
||||
* sets global variable <tt>$?</tt> to the process status:
|
||||
* Returns the <tt>$stdout</tt> output from running +command+ in a subshell;
|
||||
* sets global variable <tt>$?</tt> to the process status.
|
||||
*
|
||||
* This method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* $ `date` # => "Wed Apr 9 08:56:30 CDT 2003\n"
|
||||
* $ `echo oops && exit 99` # => "oops\n"
|
||||
|
@ -11196,36 +11204,29 @@ io_s_foreach(VALUE v)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* IO.foreach(command, sep = $/, **opts) {|line| block } -> nil
|
||||
* IO.foreach(command, limit, **opts) {|line| block } -> nil
|
||||
* IO.foreach(command, sep, limit, **opts) {|line| block } -> nil
|
||||
* IO.foreach(path, sep = $/, **opts) {|line| block } -> nil
|
||||
* IO.foreach(path, limit, **opts) {|line| block } -> nil
|
||||
* IO.foreach(path, sep, limit, **opts) {|line| block } -> nil
|
||||
* IO.foreach(command, sep = $/, **opts) {|line| block } -> nil
|
||||
* IO.foreach(command, limit, **opts) {|line| block } -> nil
|
||||
* IO.foreach(command, sep, limit, **opts) {|line| block } -> nil
|
||||
* IO.foreach(...) -> an_enumerator
|
||||
*
|
||||
* Calls the block with each successive line read from the stream.
|
||||
*
|
||||
* The first argument must be a string;
|
||||
* its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>):
|
||||
* When called from class \IO (but not subclasses of \IO),
|
||||
* this method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
* - If so (and if +self+ is \IO),
|
||||
* The first argument must be a string that is one of the following:
|
||||
*
|
||||
* - Path: if +self+ is a subclass of \IO (\File, for example),
|
||||
* or if the string _does_ _not_ start with the pipe character (<tt>'|'</tt>),
|
||||
* the string is the path to a file.
|
||||
* - Command: if +self+ is the class \IO,
|
||||
* and if the string starts with the pipe character,
|
||||
* the rest of the string is a command to be executed as a subprocess.
|
||||
* - Otherwise, the string is the path to a file.
|
||||
*
|
||||
* With only argument +command+ given, executes the command in a shell,
|
||||
* parses its $stdout into lines, as determined by the default line separator,
|
||||
* and calls the block with each successive line:
|
||||
*
|
||||
* IO.foreach('| cat t.txt') {|line| p line }
|
||||
*
|
||||
* Output:
|
||||
*
|
||||
* "First line\n"
|
||||
* "Second line\n"
|
||||
* "\n"
|
||||
* "Third line\n"
|
||||
* "Fourth line\n"
|
||||
* See the {Note on Security}[@Note+on+Security].
|
||||
*
|
||||
* With only argument +path+ given, parses lines from the file at the given +path+,
|
||||
* as determined by the default line separator,
|
||||
|
@ -11327,6 +11328,10 @@ io_s_readlines(VALUE v)
|
|||
*
|
||||
* Returns an array of all lines read from the stream.
|
||||
*
|
||||
* When called from class \IO (but not subclasses of \IO),
|
||||
* this method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
* The first argument must be a string;
|
||||
* its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>):
|
||||
*
|
||||
|
@ -11427,6 +11432,10 @@ seek_before_access(VALUE argp)
|
|||
* Opens the stream, reads and returns some or all of its content,
|
||||
* and closes the stream; returns +nil+ if no bytes were read.
|
||||
*
|
||||
* When called from class \IO (but not subclasses of \IO),
|
||||
* this method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
* The first argument must be a string;
|
||||
* its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>):
|
||||
*
|
||||
|
@ -11498,6 +11507,10 @@ rb_io_s_read(int argc, VALUE *argv, VALUE io)
|
|||
* Behaves like IO.read, except that the stream is opened in binary mode
|
||||
* with ASCII-8BIT encoding.
|
||||
*
|
||||
* When called from class \IO (but not subclasses of \IO),
|
||||
* this method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
|
@ -11599,10 +11612,14 @@ io_s_write(int argc, VALUE *argv, VALUE klass, int binary)
|
|||
* Opens the stream, writes the given +data+ to it,
|
||||
* and closes the stream; returns the number of bytes written.
|
||||
*
|
||||
* When called from class \IO (but not subclasses of \IO),
|
||||
* this method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
* The first argument must be a string;
|
||||
* its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>):
|
||||
*
|
||||
* - If so (and if +self+ is an instance of \IO),
|
||||
* - If so (and if +self+ is \IO),
|
||||
* the rest of the string is a command to be executed as a subprocess.
|
||||
* - Otherwise, the string is the path to a file.
|
||||
*
|
||||
|
@ -11660,6 +11677,10 @@ rb_io_s_write(int argc, VALUE *argv, VALUE io)
|
|||
* Behaves like IO.write, except that the stream is opened in binary mode
|
||||
* with ASCII-8BIT encoding.
|
||||
*
|
||||
* When called from class \IO (but not subclasses of \IO),
|
||||
* this method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
|
|
2
object.c
2
object.c
|
@ -4389,7 +4389,7 @@ InitVM_Object(void)
|
|||
*
|
||||
* === Subprocesses
|
||||
*
|
||||
* - #`cmd`:: Returns the standard output of running +cmd+ in a subshell.
|
||||
* - #`command`:: Returns the standard output of running +command+ in a subshell.
|
||||
* - #exec:: Replaces current process with a new process.
|
||||
* - #fork:: Forks the current process into two processes.
|
||||
* - #spawn:: Executes the given command and returns its pid without waiting
|
||||
|
|
|
@ -4755,6 +4755,9 @@ rb_spawn(int argc, const VALUE *argv)
|
|||
* Executes _command..._ in a subshell.
|
||||
* _command..._ is one of following forms.
|
||||
*
|
||||
* This method has potential security vulnerabilities if called with untrusted input;
|
||||
* see {Command Injection}[command_injection.rdoc].
|
||||
*
|
||||
* [<code>commandline</code>]
|
||||
* command line string which is passed to the standard shell
|
||||
* [<code>cmdname, arg1, ...</code>]
|
||||
|
|
Loading…
Reference in a new issue