Skip to content

Commit 75fdde5

Browse files
committed
Ruby: Use a newtype instead of DataFlow::FlowState for hardcoded-data
1 parent 0d7d5a3 commit 75fdde5

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

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

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,40 @@ module HardcodedDataInterpretedAsCode {
1919
* Flow states used to distinguish value-preserving flow from taint flow.
2020
*/
2121
module FlowState {
22-
/** Flow state used to track value-preserving flow. */
23-
DataFlow::FlowState data() { result = "data" }
22+
/**
23+
* Flow state used to track value-preserving flow.
24+
* DEPRECATED: Use `Data()`
25+
*/
26+
deprecated DataFlow::FlowState data() { result = "data" }
2427

25-
/** Flow state used to tainted data (non-value preserving flow). */
26-
DataFlow::FlowState taint() { result = "taint" }
28+
/**
29+
* Flow state used to tainted data (non-value preserving flow).
30+
* DEPRECATED: Use `Taint()`
31+
*/
32+
deprecated DataFlow::FlowState taint() { result = "taint" }
33+
34+
/**
35+
* Flow states used to distinguish value-preserving flow from taint flow.
36+
*/
37+
newtype State =
38+
Data() or
39+
Taint()
2740
}
2841

2942
/**
3043
* A data flow source for hard-coded data.
3144
*/
3245
abstract class Source extends DataFlow::Node {
33-
/** Gets a flow label for which this is a source. */
34-
DataFlow::FlowState getLabel() { result = FlowState::data() }
46+
/**
47+
* Gets a flow label for which this is a source.
48+
* DEPRECATED: Use `getALabel()`
49+
*/
50+
deprecated DataFlow::FlowState getLabel() { result = FlowState::data() }
51+
52+
/**
53+
* Gets a flow label for which this is a source.
54+
*/
55+
FlowState::State getALabel() { result = FlowState::Data() }
3556
}
3657

3758
/**
@@ -41,13 +62,26 @@ module HardcodedDataInterpretedAsCode {
4162
/** Gets a description of what kind of sink this is. */
4263
abstract string getKind();
4364

44-
/** Gets a flow label for which this is a sink. */
45-
DataFlow::FlowState getLabel() {
65+
/**
66+
* Gets a flow label for which this is a sink.
67+
* DEPRECATED: Use `getALabel()`
68+
*/
69+
deprecated DataFlow::FlowState getLabel() {
4670
// We want to ignore value-flow and only consider taint-flow, since the
4771
// source is just a hex string, and evaluating that directly will just
4872
// cause a syntax error.
4973
result = FlowState::taint()
5074
}
75+
76+
/**
77+
* Gets a flow label for which this is a sink.
78+
*/
79+
FlowState::State getALabel() {
80+
// We want to ignore value-flow and only consider taint-flow, since the
81+
// source is just a hex string, and evaluating that directly will just
82+
// cause a syntax error.
83+
result = FlowState::Taint()
84+
}
5185
}
5286

5387
/** A sanitizer for hard-coded data. */

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,33 +45,33 @@ deprecated class Configuration extends DataFlow::Configuration {
4545
}
4646
}
4747

48-
/*
49-
* We implement `DataFlow::ConfigSig` rather than
50-
* `TaintTracking::ConfigSig`, so that we can set the flow state to
51-
* `"taint"` on a taint step.
52-
*/
53-
5448
private module Config implements DataFlow::StateConfigSig {
55-
class FlowState = DataFlow::FlowState;
49+
class FlowState = FlowState::State;
5650

57-
predicate isSource(DataFlow::Node source, FlowState label) { source.(Source).getLabel() = label }
51+
predicate isSource(DataFlow::Node source, FlowState label) { source.(Source).getALabel() = label }
5852

59-
predicate isSink(DataFlow::Node sink, FlowState label) { sink.(Sink).getLabel() = label }
53+
predicate isSink(DataFlow::Node sink, FlowState label) { sink.(Sink).getALabel() = label }
6054

6155
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
6256

6357
predicate isAdditionalFlowStep(
64-
DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo,
65-
DataFlow::FlowState stateTo
58+
DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo
6659
) {
6760
defaultAdditionalTaintStep(nodeFrom, nodeTo) and
6861
// This is a taint step, so the flow state becomes `taint`.
69-
stateFrom = [FlowState::data(), FlowState::taint()] and
70-
stateTo = FlowState::taint()
62+
(
63+
stateFrom = FlowState::Taint()
64+
or
65+
stateFrom = FlowState::Data()
66+
) and
67+
stateTo = FlowState::Taint()
7168
}
7269
}
7370

7471
/**
7572
* Taint-tracking for reasoning about hard-coded data being interpreted as code.
73+
* We implement `DataFlow::GlobalWithState` rather than
74+
* `TaintTracking::GlobalWithState`, so that we can set the flow state to
75+
* `Taint()` on a taint step.
7676
*/
7777
module HardcodedDataInterpretedAsCodeFlow = DataFlow::GlobalWithState<Config>;

0 commit comments

Comments
 (0)