Skip to content

Commit 685389d

Browse files
authored
Merge pull request github#9797 from github/nickrolfe/railties_fix
Ruby: fix defining every dataflow node as a command execution sink
2 parents 70838fe + 217c9a8 commit 685389d

File tree

6 files changed

+29
-7
lines changed

6 files changed

+29
-7
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist:
5+
* The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem.
6+
* The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`.

ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ module PosixSpawn {
6262
// is shell interpreted unless there is another argument with a string
6363
// constant value.
6464
override predicate isShellInterpreted(DataFlow::Node arg) {
65+
this.argument(arg) and
6566
not exists(DataFlow::Node otherArg |
6667
otherArg != arg and
67-
this.argument(arg) and
6868
this.argument(otherArg) and
6969
otherArg.asExpr().getConstantValue().isString(_)
7070
)

ruby/ql/lib/codeql/ruby/frameworks/Railties.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ module Railties {
4343

4444
override DataFlow::Node getAnArgument() { result = this.getArgument([0, 1]) }
4545

46-
override predicate isShellInterpreted(DataFlow::Node arg) { any() }
46+
override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() }
4747
}
4848

4949
/**
@@ -57,6 +57,6 @@ module Railties {
5757

5858
override DataFlow::Node getAnArgument() { result = this.getArgument(0) }
5959

60-
override predicate isShellInterpreted(DataFlow::Node arg) { any() }
60+
override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() }
6161
}
6262
}

ruby/ql/test/library-tests/frameworks/PosixSpawn.ql

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import codeql.ruby.DataFlow
55
query predicate systemCalls(
66
PosixSpawn::SystemCall call, DataFlow::Node arg, boolean shellInterpreted
77
) {
8-
arg = call.getAnArgument() and
9-
if call.isShellInterpreted(arg) then shellInterpreted = true else shellInterpreted = false
8+
call.isShellInterpreted(arg) and shellInterpreted = true
9+
or
10+
not call.isShellInterpreted(arg) and arg = call.getAnArgument() and shellInterpreted = false
1011
}
1112

1213
query predicate childCalls(PosixSpawn::ChildCall call, DataFlow::Node arg, boolean shellInterpreted) {
13-
arg = call.getAnArgument() and
14-
if call.isShellInterpreted(arg) then shellInterpreted = true else shellInterpreted = false
14+
call.isShellInterpreted(arg) and shellInterpreted = true
15+
or
16+
not call.isShellInterpreted(arg) and arg = call.getAnArgument() and shellInterpreted = false
1517
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
systemCommandExecutions
12
| Railties.rb:5:5:5:34 | call to execute_command |
23
| Railties.rb:6:5:6:37 | call to execute_command |
34
| Railties.rb:8:5:8:16 | call to rake |
45
| Railties.rb:10:5:10:27 | call to rails_command |
56
| Railties.rb:12:5:12:17 | call to git |
7+
shellInterpretedArguments
8+
| Railties.rb:5:5:5:34 | call to execute_command | Railties.rb:5:21:5:25 | :rake |
9+
| Railties.rb:5:5:5:34 | call to execute_command | Railties.rb:5:28:5:33 | "test" |
10+
| Railties.rb:6:5:6:37 | call to execute_command | Railties.rb:6:21:6:26 | :rails |
11+
| Railties.rb:6:5:6:37 | call to execute_command | Railties.rb:6:29:6:36 | "server" |
12+
| Railties.rb:8:5:8:16 | call to rake | Railties.rb:8:10:8:15 | "test" |
13+
| Railties.rb:10:5:10:27 | call to rails_command | Railties.rb:10:19:10:26 | "server" |
14+
| Railties.rb:12:5:12:17 | call to git | Railties.rb:12:9:12:16 | "status" |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
private import ruby
22
private import codeql.ruby.Concepts
33
private import codeql.ruby.frameworks.Railties
4+
private import codeql.ruby.DataFlow
45

56
query predicate systemCommandExecutions(SystemCommandExecution e) { any() }
7+
8+
query predicate shellInterpretedArguments(SystemCommandExecution e, DataFlow::Node arg) {
9+
e.isShellInterpreted(arg)
10+
}

0 commit comments

Comments
 (0)