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

Skip to content

Commit 45dd38d

Browse files
authored
polish up dataflow query
1 parent e838b83 commit 45dd38d

1 file changed

Lines changed: 36 additions & 9 deletions

File tree

ruby/ql/src/experimental/weak-params/WeakParams.ql

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,38 @@ import codeql.ruby.DataFlow
1414
import codeql.ruby.TaintTracking
1515
import DataFlow::PathGraph
1616

17+
/**
18+
* any direct parameters reference that happens outside of a strong params method but inside
19+
* of a controller class
20+
*/
1721
class WeakParams extends Expr {
1822
WeakParams() {
19-
allParamsAccess(this) or
20-
this instanceof ParamsReference
23+
(
24+
allParamsAccess(this) or
25+
this instanceof ParamsReference
26+
) and
27+
this.getEnclosingModule() instanceof ControllerClass and
28+
not this.getEnclosingMethod() instanceof StrongParamsMethod
2129
}
2230
}
2331

32+
/**
33+
* A controller class, which extendsd `ApplicationController`
34+
*/
2435
class ControllerClass extends ModuleBase {
2536
ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" }
2637
}
2738

39+
/**
40+
* A method that follows the strong params naming convention
41+
*/
2842
class StrongParamsMethod extends Method {
2943
StrongParamsMethod() { this.getName().regexpMatch(".*_params") }
3044
}
3145

46+
/**
47+
* a call to a method that exposes or accesses all parameters from an inbound HTTP request
48+
*/
3249
predicate allParamsAccess(MethodCall call) {
3350
call.getMethodName() = "expose_all" or
3451
call.getMethodName() = "original_hash" or
@@ -39,17 +56,28 @@ predicate allParamsAccess(MethodCall call) {
3956
call.getMethodName() = "POST"
4057
}
4158

59+
/**
60+
* A reference to an element in the `params` object
61+
*/
4262
class ParamsReference extends ElementReference {
4363
ParamsReference() { this.getAChild().toString() = "params" }
4464
}
4565

66+
/**
67+
* returns either Model or ViewModel classes with a base class of `ViewModel` or includes `ActionModel::Model`,
68+
* which are required to support the strong parameters pattern
69+
*/
4670
class ModelClass extends ModuleBase {
4771
ModelClass() {
4872
this.getModule().getSuperClass+().toString() = "ViewModel" or
4973
this.getModule().getSuperClass+().getAnIncludedModule().toString() = "ActionModel::Model"
5074
}
5175
}
5276

77+
/**
78+
* A DataFlow::Node representation that corresponds to any argument passed into a method call
79+
* where the receiver is an instance of ModelClass
80+
*/
5381
class ModelClassMethodArgument extends DataFlow::Node {
5482
private DataFlow::CallNode call;
5583

@@ -59,6 +87,10 @@ class ModelClassMethodArgument extends DataFlow::Node {
5987
}
6088
}
6189

90+
/**
91+
* Taint tracking config where the source is a weak params access in a controller and the sink
92+
* is a method call of a model class
93+
*/
6294
class Configuration extends TaintTracking::Configuration {
6395
Configuration() { this = "Configuration" }
6496

@@ -70,10 +102,5 @@ class Configuration extends TaintTracking::Configuration {
70102

71103
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
72104
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."
105+
select sink.getNode().(ModelClassMethodArgument), source, sink,
106+
"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. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html"

0 commit comments

Comments
 (0)