Skip to content

Commit 79ad7d2

Browse files
committed
Ruby: make SensitiveExpr a dataflow node rather than an Expr
1 parent 0da367f commit 79ad7d2

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,15 @@ module ExprNodes {
684684
final ExprCfgNode getValue() { e.hasCfgChild(e.getValue(), this, result) }
685685
}
686686

687+
/** A control-flow node that wraps a `VariableAccess` AST expression. */
688+
class VariableAccessCfgNode extends ExprCfgNode {
689+
override string getAPrimaryQlClass() { result = "VariableAccessCfgNode" }
690+
691+
override VariableAccess e;
692+
693+
final override VariableAccess getExpr() { result = ExprCfgNode.super.getExpr() }
694+
}
695+
687696
/** A control-flow node that wraps a `VariableReadAccess` AST expression. */
688697
class VariableReadAccessCfgNode extends ExprCfgNode {
689698
override string getAPrimaryQlClass() { result = "VariableReadAccessCfgNode" }

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ private import codeql.ruby.AST
1313
private import codeql.ruby.DataFlow
1414
import codeql.ruby.security.internal.SensitiveDataHeuristics
1515
private import HeuristicNames
16+
private import codeql.ruby.CFG
1617

1718
/** An expression that might contain sensitive data. */
1819
cached
19-
abstract class SensitiveExpr extends Expr {
20+
abstract class SensitiveNode extends DataFlow::Node {
2021
/** Gets a human-readable description of this expression for use in alert messages. */
2122
cached
2223
abstract string describe();
@@ -27,32 +28,36 @@ abstract class SensitiveExpr extends Expr {
2728
}
2829

2930
/** A method call that might produce sensitive data. */
30-
class SensitiveCall extends SensitiveExpr, MethodCall {
31+
class SensitiveCall extends SensitiveNode instanceof DataFlow::CallNode {
3132
SensitiveDataClassification classification;
3233

3334
SensitiveCall() {
3435
classification = this.getMethodName().(SensitiveDataMethodName).getClassification()
3536
or
3637
// This is particularly to pick up methods with an argument like "password", which
3738
// may indicate a lookup.
38-
exists(string s | this.getAnArgument().getConstantValue().isStringlikeValue(s) |
39+
exists(string s | super.getArgument(_).asExpr().getConstantValue().isStringlikeValue(s) |
3940
nameIndicatesSensitiveData(s, classification)
4041
)
4142
}
4243

43-
override string describe() { result = "a call to " + this.getMethodName() }
44+
override string describe() { result = "a call to " + super.getMethodName() }
4445

4546
override SensitiveDataClassification getClassification() { result = classification }
4647
}
4748

4849
/** An access to a variable or hash value that might contain sensitive data. */
49-
abstract class SensitiveVariableAccess extends SensitiveExpr {
50+
abstract class SensitiveVariableAccess extends SensitiveNode {
5051
string name;
5152

5253
SensitiveVariableAccess() {
53-
this.(VariableAccess).getVariable().hasName(name)
54+
this.asExpr().(CfgNodes::ExprNodes::VariableAccessCfgNode).getExpr().getVariable().hasName(name)
5455
or
55-
this.(ElementReference).getAnArgument().getConstantValue().isStringlikeValue(name)
56+
this.asExpr()
57+
.(CfgNodes::ExprNodes::ElementReferenceCfgNode)
58+
.getAnArgument()
59+
.getConstantValue()
60+
.isStringlikeValue(name)
5661
}
5762

5863
override string describe() { result = "an access to " + name }

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,10 @@ private predicate localFlowWithElementReference(DataFlow::LocalSourceNode src, D
3434

3535
from
3636
HTTP::Server::RequestHandler handler, HTTP::Server::RequestInputAccess input,
37-
DataFlow::Node sensitive
37+
SensitiveNode sensitive
3838
where
3939
handler.getAnHttpMethod() = "get" and
4040
input.asExpr().getExpr().getEnclosingMethod() = handler and
41-
sensitive.asExpr().getExpr() instanceof SensitiveExpr and
4241
localFlowWithElementReference(input, sensitive)
4342
select input, "$@ for GET requests uses query parameter as sensitive data.", handler,
4443
"Route handler"

0 commit comments

Comments
 (0)