mirror of
https://github.com/github/codeql.git
synced 2026-04-27 01:35:13 +02:00
Merge pull request #10680 from erik-krogh/unsafeRbCmd
RB: add an unsafe-shell-command-construction query
This commit is contained in:
@@ -15,6 +15,8 @@ edges
|
||||
| CommandInjection.rb:81:20:81:25 | **args : | CommandInjection.rb:82:22:82:25 | args : |
|
||||
| CommandInjection.rb:82:22:82:25 | args : | CommandInjection.rb:82:22:82:37 | ...[...] : |
|
||||
| CommandInjection.rb:82:22:82:37 | ...[...] : | CommandInjection.rb:82:14:82:39 | "echo #{...}" |
|
||||
| CommandInjection.rb:94:16:94:21 | call to params : | CommandInjection.rb:94:16:94:28 | ...[...] : |
|
||||
| CommandInjection.rb:94:16:94:28 | ...[...] : | CommandInjection.rb:95:16:95:28 | "cat #{...}" |
|
||||
nodes
|
||||
| CommandInjection.rb:6:15:6:20 | call to params : | semmle.label | call to params : |
|
||||
| CommandInjection.rb:6:15:6:26 | ...[...] : | semmle.label | ...[...] : |
|
||||
@@ -37,6 +39,9 @@ nodes
|
||||
| CommandInjection.rb:82:14:82:39 | "echo #{...}" | semmle.label | "echo #{...}" |
|
||||
| CommandInjection.rb:82:22:82:25 | args : | semmle.label | args : |
|
||||
| CommandInjection.rb:82:22:82:37 | ...[...] : | semmle.label | ...[...] : |
|
||||
| CommandInjection.rb:94:16:94:21 | call to params : | semmle.label | call to params : |
|
||||
| CommandInjection.rb:94:16:94:28 | ...[...] : | semmle.label | ...[...] : |
|
||||
| CommandInjection.rb:95:16:95:28 | "cat #{...}" | semmle.label | "cat #{...}" |
|
||||
subpaths
|
||||
#select
|
||||
| CommandInjection.rb:7:10:7:15 | #{...} | CommandInjection.rb:6:15:6:20 | call to params : | CommandInjection.rb:7:10:7:15 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
|
||||
@@ -51,3 +56,4 @@ subpaths
|
||||
| CommandInjection.rb:65:14:65:29 | "echo #{...}" | CommandInjection.rb:64:18:64:23 | number : | CommandInjection.rb:65:14:65:29 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:64:18:64:23 | number | user-provided value |
|
||||
| CommandInjection.rb:73:14:73:34 | "echo #{...}" | CommandInjection.rb:72:23:72:33 | blah_number : | CommandInjection.rb:73:14:73:34 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:72:23:72:33 | blah_number | user-provided value |
|
||||
| CommandInjection.rb:82:14:82:39 | "echo #{...}" | CommandInjection.rb:81:20:81:25 | **args : | CommandInjection.rb:82:14:82:39 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:81:20:81:25 | **args | user-provided value |
|
||||
| CommandInjection.rb:95:16:95:28 | "cat #{...}" | CommandInjection.rb:94:16:94:21 | call to params : | CommandInjection.rb:95:16:95:28 | "cat #{...}" | This command depends on a $@. | CommandInjection.rb:94:16:94:21 | call to params | user-provided value |
|
||||
|
||||
@@ -88,3 +88,13 @@ module Types
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Foo < ActionController::Base
|
||||
def create
|
||||
file = params[:file]
|
||||
system("cat #{file}")
|
||||
# .shellescape
|
||||
system("cat #{file.shellescape}") # OK, because file is shell escaped
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
edges
|
||||
| impl/sub/notImported.rb:2:12:2:17 | target : | impl/sub/notImported.rb:3:19:3:27 | #{...} |
|
||||
| impl/sub/other2.rb:2:12:2:17 | target : | impl/sub/other2.rb:3:19:3:27 | #{...} |
|
||||
| impl/sub/other.rb:2:12:2:17 | target : | impl/sub/other.rb:3:19:3:27 | #{...} |
|
||||
| impl/unsafeShell.rb:2:12:2:17 | target : | impl/unsafeShell.rb:3:19:3:27 | #{...} |
|
||||
| impl/unsafeShell.rb:6:12:6:12 | x : | impl/unsafeShell.rb:7:32:7:32 | x |
|
||||
| impl/unsafeShell.rb:15:47:15:64 | innocent_file_path : | impl/unsafeShell.rb:20:21:20:41 | #{...} |
|
||||
| impl/unsafeShell.rb:23:15:23:23 | file_path : | impl/unsafeShell.rb:26:19:26:30 | #{...} |
|
||||
| impl/unsafeShell.rb:33:12:33:17 | target : | impl/unsafeShell.rb:34:19:34:27 | #{...} |
|
||||
| impl/unsafeShell.rb:37:10:37:10 | x : | impl/unsafeShell.rb:38:19:38:22 | #{...} |
|
||||
| impl/unsafeShell.rb:47:16:47:21 | target : | impl/unsafeShell.rb:48:19:48:27 | #{...} |
|
||||
nodes
|
||||
| impl/sub/notImported.rb:2:12:2:17 | target : | semmle.label | target : |
|
||||
| impl/sub/notImported.rb:3:19:3:27 | #{...} | semmle.label | #{...} |
|
||||
| impl/sub/other2.rb:2:12:2:17 | target : | semmle.label | target : |
|
||||
| impl/sub/other2.rb:3:19:3:27 | #{...} | semmle.label | #{...} |
|
||||
| impl/sub/other.rb:2:12:2:17 | target : | semmle.label | target : |
|
||||
| impl/sub/other.rb:3:19:3:27 | #{...} | semmle.label | #{...} |
|
||||
| impl/unsafeShell.rb:2:12:2:17 | target : | semmle.label | target : |
|
||||
| impl/unsafeShell.rb:3:19:3:27 | #{...} | semmle.label | #{...} |
|
||||
| impl/unsafeShell.rb:6:12:6:12 | x : | semmle.label | x : |
|
||||
| impl/unsafeShell.rb:7:32:7:32 | x | semmle.label | x |
|
||||
| impl/unsafeShell.rb:15:47:15:64 | innocent_file_path : | semmle.label | innocent_file_path : |
|
||||
| impl/unsafeShell.rb:20:21:20:41 | #{...} | semmle.label | #{...} |
|
||||
| impl/unsafeShell.rb:23:15:23:23 | file_path : | semmle.label | file_path : |
|
||||
| impl/unsafeShell.rb:26:19:26:30 | #{...} | semmle.label | #{...} |
|
||||
| impl/unsafeShell.rb:33:12:33:17 | target : | semmle.label | target : |
|
||||
| impl/unsafeShell.rb:34:19:34:27 | #{...} | semmle.label | #{...} |
|
||||
| impl/unsafeShell.rb:37:10:37:10 | x : | semmle.label | x : |
|
||||
| impl/unsafeShell.rb:38:19:38:22 | #{...} | semmle.label | #{...} |
|
||||
| impl/unsafeShell.rb:47:16:47:21 | target : | semmle.label | target : |
|
||||
| impl/unsafeShell.rb:48:19:48:27 | #{...} | semmle.label | #{...} |
|
||||
subpaths
|
||||
#select
|
||||
| impl/sub/notImported.rb:3:14:3:28 | "cat #{...}" | impl/sub/notImported.rb:2:12:2:17 | target : | impl/sub/notImported.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/notImported.rb:2:12:2:17 | target | library input | impl/sub/notImported.rb:3:5:3:34 | call to popen | shell command |
|
||||
| impl/sub/other2.rb:3:14:3:28 | "cat #{...}" | impl/sub/other2.rb:2:12:2:17 | target : | impl/sub/other2.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/other2.rb:2:12:2:17 | target | library input | impl/sub/other2.rb:3:5:3:34 | call to popen | shell command |
|
||||
| impl/sub/other.rb:3:14:3:28 | "cat #{...}" | impl/sub/other.rb:2:12:2:17 | target : | impl/sub/other.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/sub/other.rb:2:12:2:17 | target | library input | impl/sub/other.rb:3:5:3:34 | call to popen | shell command |
|
||||
| impl/unsafeShell.rb:3:14:3:28 | "cat #{...}" | impl/unsafeShell.rb:2:12:2:17 | target : | impl/unsafeShell.rb:3:19:3:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:2:12:2:17 | target | library input | impl/unsafeShell.rb:3:5:3:34 | call to popen | shell command |
|
||||
| impl/unsafeShell.rb:7:14:7:33 | call to sprintf | impl/unsafeShell.rb:6:12:6:12 | x : | impl/unsafeShell.rb:7:32:7:32 | x | This formatted string which depends on $@ is later used in a $@. | impl/unsafeShell.rb:6:12:6:12 | x | library input | impl/unsafeShell.rb:8:5:8:25 | call to popen | shell command |
|
||||
| impl/unsafeShell.rb:20:14:20:42 | "which #{...}" | impl/unsafeShell.rb:15:47:15:64 | innocent_file_path : | impl/unsafeShell.rb:20:21:20:41 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:15:47:15:64 | innocent_file_path | library input | impl/unsafeShell.rb:20:5:20:48 | call to popen | shell command |
|
||||
| impl/unsafeShell.rb:26:14:26:31 | "cat #{...}" | impl/unsafeShell.rb:23:15:23:23 | file_path : | impl/unsafeShell.rb:26:19:26:30 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:23:15:23:23 | file_path | library input | impl/unsafeShell.rb:26:5:26:37 | call to popen | shell command |
|
||||
| impl/unsafeShell.rb:34:14:34:28 | "cat #{...}" | impl/unsafeShell.rb:33:12:33:17 | target : | impl/unsafeShell.rb:34:19:34:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:33:12:33:17 | target | library input | impl/unsafeShell.rb:34:5:34:34 | call to popen | shell command |
|
||||
| impl/unsafeShell.rb:38:14:38:23 | "cat #{...}" | impl/unsafeShell.rb:37:10:37:10 | x : | impl/unsafeShell.rb:38:19:38:22 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:37:10:37:10 | x | library input | impl/unsafeShell.rb:38:5:38:29 | call to popen | shell command |
|
||||
| impl/unsafeShell.rb:48:14:48:28 | "cat #{...}" | impl/unsafeShell.rb:47:16:47:21 | target : | impl/unsafeShell.rb:48:19:48:27 | #{...} | This string construction which depends on $@ is later used in a $@. | impl/unsafeShell.rb:47:16:47:21 | target | library input | impl/unsafeShell.rb:48:5:48:34 | call to popen | shell command |
|
||||
@@ -0,0 +1 @@
|
||||
queries/security/cwe-078/UnsafeShellCommandConstruction.ql
|
||||
@@ -0,0 +1,6 @@
|
||||
class Foobar
|
||||
def foo1(target)
|
||||
IO.popen("cat #{target}", "w") # NOT OK - everything assumed to be imported...
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class Foobar
|
||||
def foo1(target)
|
||||
IO.popen("cat #{target}", "w") # NOT OK
|
||||
end
|
||||
end
|
||||
|
||||
require 'sub/other2'
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foobar
|
||||
def foo1(target)
|
||||
IO.popen("cat #{target}", "w") # NOT OK
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
class Foobar
|
||||
def foo1(target)
|
||||
IO.popen("cat #{target}", "w") # NOT OK
|
||||
end
|
||||
|
||||
def foo2(x)
|
||||
format = sprintf("cat %s", x) # NOT OK
|
||||
IO.popen(format, "w")
|
||||
end
|
||||
|
||||
def fileRead1(path)
|
||||
File.read(path) # OK
|
||||
end
|
||||
|
||||
def my_exec(cmd, command, myCmd, myCommand, innocent_file_path)
|
||||
IO.popen("which #{cmd}", "w") # OK - the parameter is named `cmd`, so it's meant to be a command
|
||||
IO.popen("which #{command}", "w") # OK - the parameter is named `command`, so it's meant to be a command
|
||||
IO.popen("which #{myCmd}", "w") # OK - the parameter is named `myCmd`, so it's meant to be a command
|
||||
IO.popen("which #{myCommand}", "w") # OK - the parameter is named `myCommand`, so it's meant to be a command
|
||||
IO.popen("which #{innocent_file_path}", "w") # NOT OK - the parameter is named `innocent_file_path`, so it's not meant to be a command
|
||||
end
|
||||
|
||||
def escaped(file_path)
|
||||
IO.popen("cat #{file_path.shellescape}", "w") # OK - the parameter is escaped
|
||||
|
||||
IO.popen("cat #{file_path}", "w") # NOT OK - the parameter is not escaped
|
||||
end
|
||||
end
|
||||
|
||||
require File.join(File.dirname(__FILE__), 'sub', 'other')
|
||||
|
||||
class Foobar2
|
||||
def foo1(target)
|
||||
IO.popen("cat #{target}", "w") # NOT OK
|
||||
end
|
||||
|
||||
def id(x)
|
||||
IO.popen("cat #{x}", "w") # NOT OK - the parameter is not a constant.
|
||||
return x
|
||||
end
|
||||
|
||||
def thisIsSafe()
|
||||
IO.popen("echo #{id('foo')}", "w") # OK - only using constants.
|
||||
end
|
||||
|
||||
# class methods
|
||||
def self.foo(target)
|
||||
IO.popen("cat #{target}", "w") # NOT OK
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
Gem::Specification.new do |s|
|
||||
s.name = 'unsafe-shell'
|
||||
s.require_path = "impl"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user