Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e838b83

Browse files
authored
attempt to introduce dataflow tracking
1 parent 53729f9 commit e838b83

1 file changed

Lines changed: 48 additions & 21 deletions

File tree

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @name Weak or direct parameter references are used
33
* @description Directly checking request parameters without following a strong params pattern can lead to unintentional avenues for injection attacks.
4-
* @kind problem
4+
* @kind path-problem
55
* @problem.severity error
66
* @security-severity 5.0
77
* @precision low
@@ -10,10 +10,13 @@
1010
*/
1111

1212
import ruby
13+
import codeql.ruby.DataFlow
14+
import codeql.ruby.TaintTracking
15+
import DataFlow::PathGraph
1316

14-
class WeakParams extends AstNode {
17+
class WeakParams extends Expr {
1518
WeakParams() {
16-
this instanceof UnspecificParamsMethod or
19+
allParamsAccess(this) or
1720
this instanceof ParamsReference
1821
}
1922
}
@@ -26,27 +29,51 @@ class StrongParamsMethod extends Method {
2629
StrongParamsMethod() { this.getName().regexpMatch(".*_params") }
2730
}
2831

29-
class UnspecificParamsMethod extends MethodCall {
30-
UnspecificParamsMethod() {
31-
(
32-
this.getMethodName() = "expose_all" or
33-
this.getMethodName() = "original_hash" or
34-
this.getMethodName() = "path_parametes" or
35-
this.getMethodName() = "query_parameters" or
36-
this.getMethodName() = "request_parameters" or
37-
this.getMethodName() = "GET" or
38-
this.getMethodName() = "POST"
39-
)
40-
}
32+
predicate allParamsAccess(MethodCall call) {
33+
call.getMethodName() = "expose_all" or
34+
call.getMethodName() = "original_hash" or
35+
call.getMethodName() = "path_parametes" or
36+
call.getMethodName() = "query_parameters" or
37+
call.getMethodName() = "request_parameters" or
38+
call.getMethodName() = "GET" or
39+
call.getMethodName() = "POST"
4140
}
4241

4342
class ParamsReference extends ElementReference {
4443
ParamsReference() { this.getAChild().toString() = "params" }
4544
}
4645

47-
from WeakParams params
48-
where
49-
not params.getEnclosingMethod() instanceof StrongParamsMethod and
50-
params.getEnclosingModule() instanceof ControllerClass
51-
select params,
52-
"By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects."
46+
class ModelClass extends ModuleBase {
47+
ModelClass() {
48+
this.getModule().getSuperClass+().toString() = "ViewModel" or
49+
this.getModule().getSuperClass+().getAnIncludedModule().toString() = "ActionModel::Model"
50+
}
51+
}
52+
53+
class ModelClassMethodArgument extends DataFlow::Node {
54+
private DataFlow::CallNode call;
55+
56+
ModelClassMethodArgument() {
57+
this = call.getArgument(_) and
58+
call.getExprNode().getNode().getParent+() instanceof ModelClass
59+
}
60+
}
61+
62+
class Configuration extends TaintTracking::Configuration {
63+
Configuration() { this = "Configuration" }
64+
65+
override predicate isSource(DataFlow::Node node) { node.asExpr().getNode() instanceof WeakParams }
66+
67+
// the sink is an instance of a Model class that receives a method call
68+
override predicate isSink(DataFlow::Node node) { node instanceof ModelClassMethodArgument }
69+
}
70+
71+
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
72+
where config.hasFlowPath(source, sink)
73+
select sink.getNode().(ModelClassMethodArgument), source, sink, "This is bad"
74+
// from WeakParams params
75+
// where
76+
// not params.getEnclosingMethod() instanceof StrongParamsMethod and
77+
// params.getEnclosingModule() instanceof ControllerClass
78+
// select params,
79+
// "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects."

0 commit comments

Comments
 (0)