Skip to content

Commit 79da723

Browse files
author
Stephan Brandauer
committed
Java: only assume that _manual_ MaD sinks have been fully modeled
1 parent 6b425f1 commit 79da723

5 files changed

+22
-19
lines changed

java/ql/src/Telemetry/AutomodelApplicationModeCharacteristics.qll

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
6767

6868
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2;
6969

70-
predicate isSink(Endpoint e, string kind) {
70+
predicate isSink(Endpoint e, string kind, string provenance) {
7171
exists(string package, string type, string name, string signature, string ext, string input |
7272
sinkSpec(e, package, type, name, signature, ext, input) and
73-
ExternalFlow::sinkModel(package, type, _, name, [signature, ""], ext, input, kind, _)
73+
ExternalFlow::sinkModel(package, type, _, name, [signature, ""], ext, input, kind, provenance)
7474
)
7575
or
76-
isCustomSink(e, kind)
76+
isCustomSink(e, kind) and provenance = "custom-sink"
7777
}
7878

7979
predicate isNeutral(Endpoint e) {
@@ -200,7 +200,7 @@ private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASin
200200
UnexploitableIsCharacteristic() { this = "unexploitable (is-style boolean method)" }
201201

202202
override predicate appliesToEndpoint(Endpoint e) {
203-
not ApplicationCandidatesImpl::isSink(e, _) and
203+
not ApplicationCandidatesImpl::isSink(e, _, _) and
204204
ApplicationModeGetCallable::getCallable(e).getName().matches("is%") and
205205
ApplicationModeGetCallable::getCallable(e).getReturnType() instanceof BooleanType
206206
}
@@ -218,7 +218,7 @@ private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::Not
218218
UnexploitableExistsCharacteristic() { this = "unexploitable (existence-checking boolean method)" }
219219

220220
override predicate appliesToEndpoint(Endpoint e) {
221-
not ApplicationCandidatesImpl::isSink(e, _) and
221+
not ApplicationCandidatesImpl::isSink(e, _, _) and
222222
exists(Callable callable |
223223
callable = ApplicationModeGetCallable::getCallable(e) and
224224
callable.getName().toLowerCase() = ["exists", "notexists"] and
@@ -313,7 +313,8 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter
313313

314314
/**
315315
* A negative characteristic that indicates that an endpoint is a non-sink argument to a method whose sinks have already
316-
* been modeled.
316+
* been modeled _manually_. This is restricted to manual sinks only, because only during the manual process do we have
317+
* the expectation that all sinks present in a method have been considered.
317318
*
318319
* WARNING: These endpoints should not be used as negative samples for training, because some sinks may have been missed
319320
* when the method was modeled. Specifically, as we start using ATM to merge in new declarations, we can be less sure
@@ -324,13 +325,13 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter
324325
private class OtherArgumentToModeledMethodCharacteristic extends CharacteristicsImpl::LikelyNotASinkCharacteristic
325326
{
326327
OtherArgumentToModeledMethodCharacteristic() {
327-
this = "other argument to a method that has already been modeled"
328+
this = "other argument to a method that has already been modeled manually"
328329
}
329330

330331
override predicate appliesToEndpoint(Endpoint e) {
331-
not ApplicationCandidatesImpl::isSink(e, _) and
332+
not ApplicationCandidatesImpl::isSink(e, _, _) and
332333
exists(DataFlow::Node otherSink, Call c |
333-
ApplicationCandidatesImpl::isSink(otherSink, _) and
334+
ApplicationCandidatesImpl::isSink(otherSink, _, "manual") and
334335
c = otherSink.asExpr().(Argument).getCall() and
335336
e.asExpr() in [c.getQualifier(), c.getAnArgument()] and
336337
e != otherSink

java/ql/src/Telemetry/AutomodelApplicationModeExtractCandidates.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ where
6464
// label it as a sink for one of the sink types of query B, for which it's already a known sink. This would result in
6565
// overlap between our detected sinks and the pre-existing modeling. We assume that, if a sink has already been
6666
// modeled in a MaD model, then it doesn't belong to any additional sink types, and we don't need to reexamine it.
67-
not CharacteristicsImpl::isSink(endpoint, _) and
67+
not CharacteristicsImpl::isSink(endpoint, _, _) and
6868
meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input) and
6969
// The message is the concatenation of all sink types for which this endpoint is known neither to be a sink nor to be
7070
// a non-sink, and we surface only endpoints that have at least one such sink type.

java/ql/src/Telemetry/AutomodelFrameworkModeCharacteristics.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
5050

5151
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2;
5252

53-
predicate isSink(Endpoint e, string kind) {
53+
predicate isSink(Endpoint e, string kind, string provenance) {
5454
exists(string package, string type, string name, string signature, string ext, string input |
5555
sinkSpec(e, package, type, name, signature, ext, input) and
56-
ExternalFlow::sinkModel(package, type, _, name, [signature, ""], ext, input, kind, _)
56+
ExternalFlow::sinkModel(package, type, _, name, [signature, ""], ext, input, kind, provenance)
5757
)
5858
}
5959

@@ -154,7 +154,7 @@ private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASin
154154
UnexploitableIsCharacteristic() { this = "unexploitable (is-style boolean method)" }
155155

156156
override predicate appliesToEndpoint(Endpoint e) {
157-
not FrameworkCandidatesImpl::isSink(e, _) and
157+
not FrameworkCandidatesImpl::isSink(e, _, _) and
158158
FrameworkModeGetCallable::getCallable(e).getName().matches("is%") and
159159
FrameworkModeGetCallable::getCallable(e).getReturnType() instanceof BooleanType
160160
}
@@ -172,7 +172,7 @@ private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::Not
172172
UnexploitableExistsCharacteristic() { this = "unexploitable (existence-checking boolean method)" }
173173

174174
override predicate appliesToEndpoint(Endpoint e) {
175-
not FrameworkCandidatesImpl::isSink(e, _) and
175+
not FrameworkCandidatesImpl::isSink(e, _, _) and
176176
exists(Callable callable |
177177
callable = FrameworkModeGetCallable::getCallable(e) and
178178
callable.getName().toLowerCase() = ["exists", "notexists"] and

java/ql/src/Telemetry/AutomodelFrameworkModeExtractCandidates.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ where
2828
// label it as a sink for one of the sink types of query B, for which it's already a known sink. This would result in
2929
// overlap between our detected sinks and the pre-existing modeling. We assume that, if a sink has already been
3030
// modeled in a MaD model, then it doesn't belong to any additional sink types, and we don't need to reexamine it.
31-
not CharacteristicsImpl::isSink(endpoint, _) and
31+
not CharacteristicsImpl::isSink(endpoint, _, _) and
3232
meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input, parameterName) and
3333
// The message is the concatenation of all sink types for which this endpoint is known neither to be a sink nor to be
3434
// a non-sink, and we surface only endpoints that have at least one such sink type.

java/ql/src/Telemetry/AutomodelSharedCharacteristics.qll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ signature module CandidateSig {
5858
predicate isSanitizer(Endpoint e, EndpointType t);
5959

6060
/**
61-
* Holds if `e` is a sink with the label `kind`.
61+
* Holds if `e` is a sink with the label `kind`, and provenance `provenance`.
6262
*/
63-
predicate isSink(Endpoint e, string kind);
63+
predicate isSink(Endpoint e, string kind, string provenance);
6464

6565
/**
6666
* Holds if `e` is not a sink of any kind.
@@ -87,7 +87,7 @@ signature module CandidateSig {
8787
* implementations of endpoint characteristics exported by this module.
8888
*/
8989
module SharedCharacteristics<CandidateSig Candidate> {
90-
predicate isSink = Candidate::isSink/2;
90+
predicate isSink = Candidate::isSink/3;
9191

9292
predicate isNeutral = Candidate::isNeutral/1;
9393

@@ -282,7 +282,9 @@ module SharedCharacteristics<CandidateSig Candidate> {
282282
this = madKind + "-characteristic"
283283
}
284284

285-
override predicate appliesToEndpoint(Candidate::Endpoint e) { Candidate::isSink(e, madKind) }
285+
override predicate appliesToEndpoint(Candidate::Endpoint e) {
286+
Candidate::isSink(e, madKind, _)
287+
}
286288

287289
override Candidate::EndpointType getSinkType() { result = endpointType }
288290
}

0 commit comments

Comments
 (0)