Module: Aikido::Zen::Sinks::Kernel::Extensions
- Defined in:
- lib/aikido/zen/sinks/kernel.rb
Class Method Summary collapse
-
.scan_command(command, operation) ⇒ Aikido::Zen::Attacks::ShellInjectionAttack?
Checks if the user introduced input is trying to execute other commands using Shell Injection kind of attacks.
Instance Method Summary collapse
-
#send_arg_to_scan(args, operation) ⇒ Object
‘system, spawn` functions can be invoked in several ways.
- #spawn(*args) ⇒ Object
- #system(*args) ⇒ Object
Class Method Details
.scan_command(command, operation) ⇒ Aikido::Zen::Attacks::ShellInjectionAttack?
Checks if the user introduced input is trying to execute other commands using Shell Injection kind of attacks.
user input is detected as part of a Shell Injection Attack, or nil
if it’s safe.
21 22 23 24 25 26 |
# File 'lib/aikido/zen/sinks/kernel.rb', line 21 def self.scan_command(command, operation) SINK.scan( command: command, operation: operation ) end |
Instance Method Details
#send_arg_to_scan(args, operation) ⇒ Object
‘system, spawn` functions can be invoked in several ways. For more details, see [the documentation](ruby-doc.org/3.4.1/Kernel.html#method-i-spawn)
In our context, we care primarily about two common scenarios:
- one argument (String)
e.g.: system("ls"), system("echo something")
- two arguments (Hash, String)
e.g.: system({"foo" => "bar"}, "ls"), system({"foo" => "bar"}, "echo something")
In all other cases, we do not protect against shell argument injections. Specifically:
If a user input contains something like $(whoami) and is passed as part of the command arguments (e.g., user_input = “$(whoami)”):
system("echo", user_input) This is safe because Ruby automatically escapes arguments
passed to system/spawn in this form.
system("echo #{user_input}") This is not safe because Ruby interpolates the user_input
into the command string, resulting in a potentially harmful
command like `echo $(whoami)`.
48 49 50 51 52 53 54 55 56 |
# File 'lib/aikido/zen/sinks/kernel.rb', line 48 def send_arg_to_scan(args, operation) if args.size == 1 && args[0].is_a?(String) Extensions.scan_command(args[0], operation) end if args.size == 2 && args[0].is_a?(Hash) Extensions.scan_command(args[1], operation) end end |
#spawn(*args) ⇒ Object
63 64 65 66 |
# File 'lib/aikido/zen/sinks/kernel.rb', line 63 def spawn(*args, **) send_arg_to_scan(args, "spawn") super end |
#system(*args) ⇒ Object
58 59 60 61 |
# File 'lib/aikido/zen/sinks/kernel.rb', line 58 def system(*args, **) send_arg_to_scan(args, "system") super end |