Skip to content

Commit 0cfe37d

Browse files
committed
Share TaintedFormatString between Ruby and JS
1 parent 4249e30 commit 0cfe37d

File tree

8 files changed

+89
-72
lines changed

8 files changed

+89
-72
lines changed

config/identical-files.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,5 +525,13 @@
525525
"ApiGraphModels": [
526526
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",
527527
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll"
528+
],
529+
"TaintedFormatStringQuery Ruby/JS": [
530+
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll",
531+
"ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll"
532+
],
533+
"TaintedFormatStringCustomizations Ruby/JS": [
534+
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringCustomizations.qll",
535+
"ruby/ql/lib/codeql/ruby/security/TaintedFormatStringCustomizations.qll"
528536
]
529-
}
537+
}

javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringCustomizations.qll

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
* format injections, as well as extension points for adding your own.
44
*/
55

6-
import javascript
7-
import semmle.javascript.security.dataflow.DOM
8-
6+
/**
7+
* Provides default sources, sinks and sanitizers for reasoning about
8+
* format injections, as well as extension points for adding your own.
9+
*/
910
module TaintedFormatString {
11+
import TaintedFormatStringSpecific
12+
1013
/**
1114
* A data flow source for format injections.
1215
*/
@@ -23,9 +26,7 @@ module TaintedFormatString {
2326
abstract class Sanitizer extends DataFlow::Node { }
2427

2528
/** A source of remote user input, considered as a flow source for format injection. */
26-
class RemoteSource extends Source {
27-
RemoteSource() { this instanceof RemoteFlowSource }
28-
}
29+
class RemoteSource extends Source instanceof RemoteFlowSource { }
2930

3031
/**
3132
* A format argument to a printf-like function, considered as a flow sink for format injection.

javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
* `TaintedFormatStringCustomizations` should be imported instead.
99
*/
1010

11-
import javascript
12-
import semmle.javascript.security.dataflow.DOM
13-
import TaintedFormatStringCustomizations::TaintedFormatString
11+
private import TaintedFormatStringCustomizations::TaintedFormatString
1412

1513
/**
1614
* A taint-tracking configuration for format injections.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Provides JS-specific imports needed for `TaintedFormatStringQuery` and `TaintedFormatStringCustomizations`.
3+
*/
4+
5+
import javascript
6+
import semmle.javascript.security.dataflow.DOM

ruby/ql/lib/codeql/ruby/security/TaintedFormatStringCustomizations.qll

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33
* format injections, as well as extension points for adding your own.
44
*/
55

6-
private import ruby
7-
private import codeql.ruby.DataFlow
8-
private import codeql.ruby.dataflow.RemoteFlowSources
9-
private import codeql.ruby.ApiGraphs
10-
116
/**
127
* Provides default sources, sinks and sanitizers for reasoning about
138
* format injections, as well as extension points for adding your own.
149
*/
1510
module TaintedFormatString {
11+
import TaintedFormatStringSpecific
12+
1613
/**
1714
* A data flow source for format injections.
1815
*/
@@ -36,63 +33,11 @@ module TaintedFormatString {
3633
*/
3734
class FormatSink extends Sink {
3835
FormatSink() {
39-
exists(PrintfCall printf |
36+
exists(PrintfStyleCall printf |
4037
this = printf.getFormatString() and
4138
// exclude trivial case where there are no arguments to interpolate
4239
exists(printf.getFormatArgument(_))
4340
)
4441
}
4542
}
46-
47-
/**
48-
* A call to `printf` or `sprintf`.
49-
*/
50-
abstract class PrintfCall extends DataFlow::CallNode {
51-
// We assume that most printf-like calls have the signature f(format_string, args...)
52-
/**
53-
* Gets the format string of this call.
54-
*/
55-
DataFlow::Node getFormatString() { result = this.getArgument(0) }
56-
57-
/**
58-
* Gets then `n`th formatted argument of this call.
59-
*/
60-
DataFlow::Node getFormatArgument(int n) { n > 0 and result = this.getArgument(n) }
61-
}
62-
63-
/**
64-
* A call to `Kernel.printf`.
65-
*/
66-
class KernelPrintfCall extends PrintfCall {
67-
KernelPrintfCall() {
68-
this = API::getTopLevelMember("Kernel").getAMethodCall("printf")
69-
or
70-
this.asExpr().getExpr() instanceof UnknownMethodCall and
71-
this.getMethodName() = "printf"
72-
}
73-
74-
// Kernel#printf supports two signatures:
75-
// printf(io, string, ...)
76-
// printf(string, ...)
77-
override DataFlow::Node getFormatString() { result = this.getArgument([0, 1]) }
78-
}
79-
80-
/**
81-
* A call to `Kernel.sprintf`.
82-
*/
83-
class KernelSprintfCall extends PrintfCall {
84-
KernelSprintfCall() {
85-
this = API::getTopLevelMember("Kernel").getAMethodCall("sprintf")
86-
or
87-
this.asExpr().getExpr() instanceof UnknownMethodCall and
88-
this.getMethodName() = "sprintf"
89-
}
90-
}
91-
92-
/**
93-
* A call to `IO#printf`.
94-
*/
95-
class IOPrintfCall extends PrintfCall {
96-
IOPrintfCall() { this = API::getTopLevelMember("IO").getInstance().getAMethodCall("printf") }
97-
}
9843
}

ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@
88
* `TaintedFormatStringCustomizations` should be imported instead.
99
*/
1010

11-
import ruby
12-
import codeql.ruby.DataFlow
13-
import codeql.ruby.TaintTracking
14-
import TaintedFormatStringCustomizations::TaintedFormatString
11+
private import TaintedFormatStringCustomizations::TaintedFormatString
1512

1613
/**
1714
* A taint-tracking configuration for format injections.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Provides Ruby-specific imports and classes needed for `TaintedFormatStringQuery` and `TaintedFormatStringCustomizations`.
3+
*/
4+
5+
import ruby
6+
import codeql.ruby.DataFlow
7+
import codeql.ruby.dataflow.RemoteFlowSources
8+
import codeql.ruby.ApiGraphs
9+
import codeql.ruby.TaintTracking
10+
11+
/**
12+
* A call to `printf` or `sprintf`.
13+
*/
14+
abstract class PrintfStyleCall extends DataFlow::CallNode {
15+
// We assume that most printf-like calls have the signature f(format_string, args...)
16+
/**
17+
* Gets the format string of this call.
18+
*/
19+
DataFlow::Node getFormatString() { result = this.getArgument(0) }
20+
21+
/**
22+
* Gets then `n`th formatted argument of this call.
23+
*/
24+
DataFlow::Node getFormatArgument(int n) { n > 0 and result = this.getArgument(n) }
25+
}
26+
27+
/**
28+
* A call to `Kernel.printf`.
29+
*/
30+
class KernelPrintfCall extends PrintfStyleCall {
31+
KernelPrintfCall() {
32+
this = API::getTopLevelMember("Kernel").getAMethodCall("printf")
33+
or
34+
this.asExpr().getExpr() instanceof UnknownMethodCall and
35+
this.getMethodName() = "printf"
36+
}
37+
38+
// Kernel#printf supports two signatures:
39+
// printf(io, string, ...)
40+
// printf(string, ...)
41+
override DataFlow::Node getFormatString() { result = this.getArgument([0, 1]) }
42+
}
43+
44+
/**
45+
* A call to `Kernel.sprintf`.
46+
*/
47+
class KernelSprintfCall extends PrintfStyleCall {
48+
KernelSprintfCall() {
49+
this = API::getTopLevelMember("Kernel").getAMethodCall("sprintf")
50+
or
51+
this.asExpr().getExpr() instanceof UnknownMethodCall and
52+
this.getMethodName() = "sprintf"
53+
}
54+
}
55+
56+
/**
57+
* A call to `IO#printf`.
58+
*/
59+
class IOPrintfCall extends PrintfStyleCall {
60+
IOPrintfCall() { this = API::getTopLevelMember("IO").getInstance().getAMethodCall("printf") }
61+
}

ruby/ql/src/queries/security/cwe-134/TaintedFormatString.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212

1313
import ruby
14+
import codeql.ruby.DataFlow
1415
import codeql.ruby.security.TaintedFormatStringQuery
1516
import DataFlow::PathGraph
1617

0 commit comments

Comments
 (0)