Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 64ac49a

Browse files
author
Sauyon Lee
authored
Merge pull request #380 from sauyon/funtionmodel-shortcuts
Add utility predicates to FunctionModel
2 parents e9278b5 + e823712 commit 64ac49a

File tree

5 files changed

+46
-21
lines changed

5 files changed

+46
-21
lines changed

ql/src/Security/CWE-352/ConstantOauth2State.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class PrivateUrlFlowsToAuthCodeUrlCall extends DataFlow::Configuration {
101101
TaintTracking::referenceStep(pred, succ)
102102
or
103103
// Propagate across Sprintf and similar calls
104-
TaintTracking::functionModelStep(any(Fmt::Sprinter s), pred, succ)
104+
any(Fmt::Sprinter s).taintStep(pred, succ)
105105
}
106106

107107
predicate isSink(DataFlow::Node sink, DataFlow::CallNode call) {

ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,26 @@ class TypeCastNode extends ExprNode {
896896
abstract class FunctionModel extends Function {
897897
/** Holds if data flows through this function from `input` to `output`. */
898898
abstract predicate hasDataFlow(FunctionInput input, FunctionOutput output);
899+
900+
/** Gets an input node for this model for the call `c`. */
901+
DataFlow::Node getAnInputNode(DataFlow::CallNode c) { this.flowStepForCall(result, _, c) }
902+
903+
/** Gets an output node for this model for the call `c`. */
904+
DataFlow::Node getAnOutputNode(DataFlow::CallNode c) { this.flowStepForCall(_, result, c) }
905+
906+
/** Holds if this function model causes data to flow from `pred` to `succ` for the call `c`. */
907+
predicate flowStepForCall(DataFlow::Node pred, DataFlow::Node succ, DataFlow::CallNode c) {
908+
c = this.getACall() and
909+
exists(FunctionInput inp, FunctionOutput outp | this.hasDataFlow(inp, outp) |
910+
pred = inp.getNode(c) and
911+
succ = outp.getNode(c)
912+
)
913+
}
914+
915+
/** Holds if this function model causes data to flow from `pred` to `succ`. */
916+
predicate flowStep(DataFlow::Node pred, DataFlow::Node succ) {
917+
this.flowStepForCall(pred, succ, _)
918+
}
899919
}
900920

901921
/**
@@ -1006,12 +1026,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
10061026
basicLocalFlowStep(nodeFrom, nodeTo)
10071027
or
10081028
// step through function model
1009-
exists(FunctionModel m, CallNode c, FunctionInput inp, FunctionOutput outp |
1010-
c = m.getACall() and
1011-
m.hasDataFlow(inp, outp) and
1012-
nodeFrom = inp.getNode(c) and
1013-
nodeTo = outp.getNode(c)
1014-
)
1029+
any(FunctionModel m).flowStep(nodeFrom, nodeTo)
10151030
}
10161031

10171032
/**

ql/src/semmle/go/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ predicate localAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
6060
tupleStep(pred, succ) or
6161
stringConcatStep(pred, succ) or
6262
sliceStep(pred, succ) or
63-
functionModelStep(_, pred, succ) or
63+
any(FunctionModel fm).taintStep(pred, succ) or
6464
any(AdditionalTaintStep a).step(pred, succ)
6565
}
6666

@@ -140,23 +140,33 @@ predicate sliceStep(DataFlow::Node pred, DataFlow::Node succ) {
140140
succ.(DataFlow::SliceNode).getBase() = pred
141141
}
142142

143-
/** Holds if taint flows from `pred` to `succ` via a function model. */
144-
predicate functionModelStep(FunctionModel fn, DataFlow::Node pred, DataFlow::Node succ) {
145-
exists(DataFlow::CallNode c, FunctionInput inp, FunctionOutput outp |
146-
c = fn.getACall() and
147-
fn.hasTaintFlow(inp, outp) and
148-
pred = inp.getNode(c) and
149-
succ = outp.getNode(c)
150-
)
151-
}
152-
153143
/**
154144
* A model of a function specifying that the function propagates taint from
155145
* a parameter or qualifier to a result.
156146
*/
157147
abstract class FunctionModel extends Function {
158148
/** Holds if taint propagates through this function from `input` to `output`. */
159149
abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output);
150+
151+
/** Gets an input node for this model for the call `c`. */
152+
DataFlow::Node getAnInputNode(DataFlow::CallNode c) { this.taintStepForCall(result, _, c) }
153+
154+
/** Gets an output node for this model for the call `c`. */
155+
DataFlow::Node getAnOutputNode(DataFlow::CallNode c) { this.taintStepForCall(_, result, c) }
156+
157+
/** Holds if this function model causes taint to flow from `pred` to `succ` for the call `c`. */
158+
predicate taintStepForCall(DataFlow::Node pred, DataFlow::Node succ, DataFlow::CallNode c) {
159+
c = this.getACall() and
160+
exists(FunctionInput inp, FunctionOutput outp | this.hasTaintFlow(inp, outp) |
161+
pred = inp.getNode(c) and
162+
succ = outp.getNode(c)
163+
)
164+
}
165+
166+
/** Holds if this function model causes taint to flow from `pred` to `succ`. */
167+
predicate taintStep(DataFlow::Node pred, DataFlow::Node succ) {
168+
this.taintStepForCall(pred, succ, _)
169+
}
160170
}
161171

162172
/**

ql/src/semmle/go/security/SafeUrlFlowCustomizations.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ module SafeUrlFlow {
2525

2626
/** A function model step using `UnsafeUrlMethod`, considered as a sanitizer for safe URL flow. */
2727
private class UnsafeUrlMethodEdge extends SanitizerEdge {
28-
UnsafeUrlMethodEdge() { TaintTracking::functionModelStep(any(UnsafeUrlMethod um), this, _) }
28+
UnsafeUrlMethodEdge() { this = any(UnsafeUrlMethod um).getAnInputNode(_) }
2929
}
3030
}

ql/test/library-tests/semmle/go/dataflow/FunctionInputsAndOutputs/FunctionModelStep.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ class ReaderReset extends TaintTracking::FunctionModel, Method {
1616
}
1717
}
1818

19-
from Function fn, DataFlow::Node pred, DataFlow::Node succ
20-
where TaintTracking::functionModelStep(fn, pred, succ)
19+
from TaintTracking::FunctionModel fn, DataFlow::Node pred, DataFlow::Node succ
20+
where fn.taintStep(pred, succ)
2121
select fn, pred, succ

0 commit comments

Comments
 (0)