Skip to content

Commit 880fb2b

Browse files
committed
Ruby: split out rb/sensitive-get-query using query/customizations pattern
1 parent 703829c commit 880fb2b

File tree

4 files changed

+103
-31
lines changed

4 files changed

+103
-31
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Provides default sources and sinks for reasoning about sensitive data sourced
3+
* from the query string of a GET request, as well as extension points for
4+
* adding your own.
5+
*/
6+
7+
private import codeql.ruby.security.SensitiveActions
8+
private import codeql.ruby.Concepts
9+
private import codeql.ruby.DataFlow
10+
11+
/**
12+
* Provides default sources and sinks for reasoning about sensitive data sourced
13+
* from the query string of a GET request, as well as extension points for
14+
* adding your own.
15+
*/
16+
module SensitiveGetQuery {
17+
/**
18+
* A data flow source representing data sourced from the query string in a
19+
* GET request handler.
20+
*/
21+
abstract class Source extends DataFlow::Node {
22+
/** Gets the request handler corresponding to this data source. */
23+
abstract Http::Server::RequestHandler getHandler();
24+
}
25+
26+
/**
27+
* An access to data from the query string of a GET request as a data flow
28+
* source.
29+
*/
30+
private class RequestInputAccessSource extends Source instanceof Http::Server::RequestInputAccess {
31+
private Http::Server::RequestHandler handler;
32+
33+
RequestInputAccessSource() {
34+
handler = this.asExpr().getExpr().getEnclosingMethod() and
35+
handler.getAnHttpMethod() = "get"
36+
}
37+
38+
override Http::Server::RequestHandler getHandler() { result = handler }
39+
}
40+
41+
/**
42+
* A data flow sink suggesting a use of sensitive data.
43+
*/
44+
abstract class Sink extends DataFlow::Node { }
45+
46+
/** A sensitive data node as a data flow sink. */
47+
private class SensitiveNodeSink extends Sink instanceof SensitiveNode {
48+
SensitiveNodeSink() {
49+
// User names and other similar information is not sensitive in this context.
50+
not this.getClassification() = SensitiveDataClassification::id()
51+
}
52+
}
53+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Provides a taint-tracking configuration for detecting flow of query string
3+
* data to sensitive actions in GET query request handlers.
4+
*
5+
* Note, for performance reasons: only import this file if `Configuration` is
6+
* needed, otherwise `SensitiveGetQueryCustomizations` should be imported
7+
* instead.
8+
*/
9+
10+
private import ruby
11+
private import codeql.ruby.DataFlow
12+
private import codeql.ruby.TaintTracking
13+
14+
/**
15+
* Provides a taint-tracking configuration for detecting flow of query string
16+
* data to sensitive actions in GET query request handlers.
17+
*/
18+
module SensitiveGetQuery {
19+
import SensitiveGetQueryCustomizations::SensitiveGetQuery
20+
21+
/**
22+
* A taint-tracking configuration for reasoning about use of sensitive data
23+
* from a GET request query string.
24+
*/
25+
class Configuration extends TaintTracking::Configuration {
26+
Configuration() { this = "SensitiveGetQuery" }
27+
28+
override predicate isSource(DataFlow::Node source) { source instanceof Source }
29+
30+
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
31+
}
32+
}

ruby/ql/src/queries/security/cwe-598/SensitiveGetQuery.ql

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,13 @@
1212
*/
1313

1414
import ruby
15-
private import codeql.ruby.DataFlow
16-
private import codeql.ruby.TaintTracking
17-
private import codeql.ruby.security.SensitiveActions
18-
private import codeql.ruby.Concepts
19-
private import codeql.ruby.frameworks.ActionDispatch
20-
private import codeql.ruby.frameworks.ActionController
21-
private import codeql.ruby.frameworks.core.Array
15+
import DataFlow::PathGraph
16+
import codeql.ruby.DataFlow
17+
import codeql.ruby.security.SensitiveGetQueryQuery
18+
import codeql.ruby.security.SensitiveActions
2219

23-
class Source extends Http::Server::RequestInputAccess {
24-
private Http::Server::RequestHandler handler;
25-
26-
Source() {
27-
handler = this.asExpr().getExpr().getEnclosingMethod() and
28-
handler.getAnHttpMethod() = "get"
29-
}
30-
31-
Http::Server::RequestHandler getHandler() { result = handler }
32-
}
33-
34-
class Configuration extends TaintTracking::Configuration {
35-
Configuration() { this = "SensitiveGetQuery" }
36-
37-
override predicate isSource(DataFlow::Node source) { source instanceof Source }
38-
39-
override predicate isSink(DataFlow::Node sink) { sink instanceof SensitiveNode }
40-
}
41-
42-
from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config
43-
where
44-
config.hasFlowPath(source, sink) and
45-
not sink.getNode().(SensitiveNode).getClassification() = SensitiveDataClassification::id()
20+
from DataFlow::PathNode source, DataFlow::PathNode sink, SensitiveGetQuery::Configuration config
21+
where config.hasFlowPath(source, sink)
4622
select source.getNode(), source, sink,
4723
"$@ for GET requests uses query parameter as sensitive data.",
48-
source.getNode().(Source).getHandler(), "Route handler"
24+
source.getNode().(SensitiveGetQuery::Source).getHandler(), "Route handler"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1+
edges
2+
| app/controllers/users_controller.rb:4:16:4:21 | call to params : | app/controllers/users_controller.rb:4:16:4:32 | ...[...] |
3+
| app/controllers/users_controller.rb:4:16:4:21 | call to params : | app/controllers/users_controller.rb:4:16:4:32 | ...[...] : |
4+
| app/controllers/users_controller.rb:4:16:4:32 | ...[...] : | app/controllers/users_controller.rb:5:42:5:49 | password |
5+
nodes
6+
| app/controllers/users_controller.rb:4:16:4:21 | call to params : | semmle.label | call to params : |
7+
| app/controllers/users_controller.rb:4:16:4:32 | ...[...] | semmle.label | ...[...] |
8+
| app/controllers/users_controller.rb:4:16:4:32 | ...[...] : | semmle.label | ...[...] : |
9+
| app/controllers/users_controller.rb:5:42:5:49 | password | semmle.label | password |
10+
subpaths
11+
#select
112
| app/controllers/users_controller.rb:4:16:4:21 | call to params | app/controllers/users_controller.rb:4:16:4:21 | call to params : | app/controllers/users_controller.rb:4:16:4:32 | ...[...] | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:3:3:6:5 | login_get | Route handler |
213
| app/controllers/users_controller.rb:4:16:4:21 | call to params | app/controllers/users_controller.rb:4:16:4:21 | call to params : | app/controllers/users_controller.rb:5:42:5:49 | password | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:3:3:6:5 | login_get | Route handler |

0 commit comments

Comments
 (0)