Skip to content

Commit 99de397

Browse files
committed
Remove redundant code
`isOtherModeledArgument` and `isArgumentToBuiltinFunction` contained the old logic for selecting negative endpoints for training. These can now be deleted, and replaced by a single base class that collects all EndpointCharacteristics that are currently used to indicate negative training samples: `OtherModeledArgumentCharacteristic`. This in turn lets us delete code from `StandardEndpointFilters` that effectively said that endpoints that are high-confidence non-sinks shouldn't be scored at inference time, either.
1 parent 7b0269c commit 99de397

File tree

4 files changed

+59
-164
lines changed

4 files changed

+59
-164
lines changed

javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/CoreKnowledge.qll

Lines changed: 0 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ private import semmle.javascript.security.dataflow.HttpToFileAccessCustomization
4444
private import semmle.javascript.security.dataflow.BrokenCryptoAlgorithmCustomizations
4545
private import semmle.javascript.security.dataflow.LoopBoundInjectionCustomizations
4646
private import semmle.javascript.security.dataflow.CleartextStorageCustomizations
47-
import FilteringReasons
4847

4948
/**
5049
* Holds if the node `n` is a known sink in a modeled library, or a sibling-argument of such a sink.
@@ -110,116 +109,3 @@ predicate isKnownStepSrc(DataFlow::Node n) {
110109
DataFlow::SharedFlowStep::step(n, _) or
111110
DataFlow::SharedFlowStep::step(n, _, _, _)
112111
}
113-
114-
/**
115-
* Holds if `n` is an argument to a function of a builtin object.
116-
*/
117-
private predicate isArgumentToBuiltinFunction(DataFlow::Node n, FilteringReason reason) {
118-
exists(DataFlow::SourceNode builtin, DataFlow::SourceNode receiver, DataFlow::InvokeNode invk |
119-
(
120-
builtin instanceof DataFlow::ArrayCreationNode and
121-
reason instanceof ArgumentToArrayReason
122-
or
123-
builtin =
124-
DataFlow::globalVarRef([
125-
"Map", "Set", "WeakMap", "WeakSet", "Number", "Object", "String", "Array", "Error",
126-
"Math", "Boolean"
127-
]) and
128-
reason instanceof ArgumentToBuiltinGlobalVarRefReason
129-
)
130-
|
131-
receiver = [builtin.getAnInvocation(), builtin] and
132-
invk = [receiver, receiver.getAPropertyRead()].getAnInvocation() and
133-
invk.getAnArgument() = n
134-
)
135-
or
136-
exists(Expr primitive, MethodCallExpr c |
137-
primitive instanceof ConstantString or
138-
primitive instanceof NumberLiteral or
139-
primitive instanceof BooleanLiteral
140-
|
141-
c.calls(primitive, _) and
142-
c.getAnArgument() = n.asExpr() and
143-
reason instanceof ConstantReceiverReason
144-
)
145-
or
146-
exists(DataFlow::CallNode call |
147-
call.getAnArgument() = n and
148-
call.getCalleeName() =
149-
[
150-
"indexOf", "hasOwnProperty", "substring", "isDecimal", "decode", "encode", "keys", "shift",
151-
"values", "forEach", "toString", "slice", "splice", "push", "isArray", "sort"
152-
] and
153-
reason instanceof BuiltinCallNameReason
154-
)
155-
}
156-
157-
predicate isOtherModeledArgument(DataFlow::Node n, FilteringReason reason) {
158-
isArgumentToBuiltinFunction(n, reason)
159-
or
160-
any(LodashUnderscore::Member m).getACall().getAnArgument() = n and
161-
reason instanceof LodashUnderscoreArgumentReason
162-
or
163-
any(JQuery::MethodCall m).getAnArgument() = n and
164-
reason instanceof JQueryArgumentReason
165-
or
166-
exists(ClientRequest r |
167-
r.getAnArgument() = n or n = r.getUrl() or n = r.getHost() or n = r.getADataNode()
168-
) and
169-
reason instanceof ClientRequestReason
170-
or
171-
exists(PromiseDefinition p |
172-
n = [p.getResolveParameter(), p.getRejectParameter()].getACall().getAnArgument()
173-
) and
174-
reason instanceof PromiseDefinitionReason
175-
or
176-
n instanceof CryptographicKey and reason instanceof CryptographicKeyReason
177-
or
178-
any(CryptographicOperation op).getInput() = n and
179-
reason instanceof CryptographicOperationFlowReason
180-
or
181-
exists(DataFlow::CallNode call | n = call.getAnArgument() |
182-
call.getCalleeName() = getAStandardLoggerMethodName() and
183-
reason instanceof LoggerMethodReason
184-
or
185-
call.getCalleeName() = ["setTimeout", "clearTimeout"] and
186-
reason instanceof TimeoutReason
187-
or
188-
call.getReceiver() = DataFlow::globalVarRef(["localStorage", "sessionStorage"]) and
189-
reason instanceof ReceiverStorageReason
190-
or
191-
call instanceof StringOps::StartsWith and reason instanceof StringStartsWithReason
192-
or
193-
call instanceof StringOps::EndsWith and reason instanceof StringEndsWithReason
194-
or
195-
call instanceof StringOps::RegExpTest and reason instanceof StringRegExpTestReason
196-
or
197-
call instanceof EventRegistration and reason instanceof EventRegistrationReason
198-
or
199-
call instanceof EventDispatch and reason instanceof EventDispatchReason
200-
or
201-
call = any(MembershipCandidate c).getTest() and
202-
reason instanceof MembershipCandidateTestReason
203-
or
204-
call instanceof FileSystemAccess and reason instanceof FileSystemAccessReason
205-
or
206-
// TODO database accesses are less well defined than database query sinks, so this may cover unmodeled sinks on existing database models
207-
[
208-
call, call.getAMethodCall()
209-
/* command pattern where the query is built, and then exec'ed later */ ] instanceof
210-
DatabaseAccess and
211-
reason instanceof DatabaseAccessReason
212-
or
213-
call = DOM::domValueRef() and reason instanceof DomReason
214-
or
215-
call.getCalleeName() = "next" and
216-
exists(DataFlow::FunctionNode f | call = f.getLastParameter().getACall()) and
217-
reason instanceof NextFunctionCallReason
218-
or
219-
call = DataFlow::globalVarRef("dojo").getAPropertyRead("require").getACall() and
220-
reason instanceof DojoRequireReason
221-
)
222-
or
223-
(exists(Base64::Decode d | n = d.getInput()) or exists(Base64::Encode d | n = d.getInput())) and
224-
reason instanceof Base64ManipulationReason
225-
}

javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointCharacteristics.qll

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,19 @@ private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic {
143143
* negative samples for training.
144144
*/
145145

146+
/**
147+
* A characteristic that is an indicator of not being a sink of any type, because it's a modeled argument.
148+
*/
149+
abstract class OtherModeledArgumentCharacteristic extends EndpointCharacteristic {
150+
bindingset[this]
151+
OtherModeledArgumentCharacteristic() { any() }
152+
}
153+
146154
/**
147155
* A characteristic that is an indicator of not being a sink of any type, because it's an argument to a function of a
148156
* builtin object.
149157
*/
150-
abstract private class ArgumentToBuiltinFunctionCharacteristic extends EndpointCharacteristic {
158+
abstract private class ArgumentToBuiltinFunctionCharacteristic extends OtherModeledArgumentCharacteristic {
151159
bindingset[this]
152160
ArgumentToBuiltinFunctionCharacteristic() { any() }
153161
}
@@ -187,23 +195,26 @@ abstract class LikelyNotASinkCharacteristic extends EndpointCharacteristic {
187195
}
188196
}
189197

190-
private class LodashUnderscore extends NotASinkCharacteristic {
191-
LodashUnderscore() { this = "LodashUnderscoreArgument" }
198+
private class LodashUnderscoreCharacteristic extends NotASinkCharacteristic,
199+
OtherModeledArgumentCharacteristic {
200+
LodashUnderscoreCharacteristic() { this = "LodashUnderscoreArgument" }
192201

193202
override predicate getEndpoints(DataFlow::Node n) {
194203
any(LodashUnderscore::Member m).getACall().getAnArgument() = n
195204
}
196205
}
197206

198-
private class JQueryArgumentCharacteristic extends NotASinkCharacteristic {
207+
private class JQueryArgumentCharacteristic extends NotASinkCharacteristic,
208+
OtherModeledArgumentCharacteristic {
199209
JQueryArgumentCharacteristic() { this = "JQueryArgument" }
200210

201211
override predicate getEndpoints(DataFlow::Node n) {
202212
any(JQuery::MethodCall m).getAnArgument() = n
203213
}
204214
}
205215

206-
private class ClientRequestCharacteristic extends NotASinkCharacteristic {
216+
private class ClientRequestCharacteristic extends NotASinkCharacteristic,
217+
OtherModeledArgumentCharacteristic {
207218
ClientRequestCharacteristic() { this = "ClientRequest" }
208219

209220
override predicate getEndpoints(DataFlow::Node n) {
@@ -213,7 +224,8 @@ private class ClientRequestCharacteristic extends NotASinkCharacteristic {
213224
}
214225
}
215226

216-
private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic {
227+
private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic,
228+
OtherModeledArgumentCharacteristic {
217229
PromiseDefinitionCharacteristic() { this = "PromiseDefinition" }
218230

219231
override predicate getEndpoints(DataFlow::Node n) {
@@ -223,21 +235,24 @@ private class PromiseDefinitionCharacteristic extends NotASinkCharacteristic {
223235
}
224236
}
225237

226-
private class CryptographicKeyCharacteristic extends NotASinkCharacteristic {
238+
private class CryptographicKeyCharacteristic extends NotASinkCharacteristic,
239+
OtherModeledArgumentCharacteristic {
227240
CryptographicKeyCharacteristic() { this = "CryptographicKey" }
228241

229242
override predicate getEndpoints(DataFlow::Node n) { n instanceof CryptographicKey }
230243
}
231244

232-
private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic {
245+
private class CryptographicOperationFlowCharacteristic extends NotASinkCharacteristic,
246+
OtherModeledArgumentCharacteristic {
233247
CryptographicOperationFlowCharacteristic() { this = "CryptographicOperationFlow" }
234248

235249
override predicate getEndpoints(DataFlow::Node n) {
236250
any(CryptographicOperation op).getInput() = n
237251
}
238252
}
239253

240-
private class LoggerMethodCharacteristic extends NotASinkCharacteristic {
254+
private class LoggerMethodCharacteristic extends NotASinkCharacteristic,
255+
OtherModeledArgumentCharacteristic {
241256
LoggerMethodCharacteristic() { this = "LoggerMethod" }
242257

243258
override predicate getEndpoints(DataFlow::Node n) {
@@ -247,7 +262,8 @@ private class LoggerMethodCharacteristic extends NotASinkCharacteristic {
247262
}
248263
}
249264

250-
private class TimeoutCharacteristic extends NotASinkCharacteristic {
265+
private class TimeoutCharacteristic extends NotASinkCharacteristic,
266+
OtherModeledArgumentCharacteristic {
251267
TimeoutCharacteristic() { this = "Timeout" }
252268

253269
override predicate getEndpoints(DataFlow::Node n) {
@@ -257,7 +273,8 @@ private class TimeoutCharacteristic extends NotASinkCharacteristic {
257273
}
258274
}
259275

260-
private class ReceiverStorageCharacteristic extends NotASinkCharacteristic {
276+
private class ReceiverStorageCharacteristic extends NotASinkCharacteristic,
277+
OtherModeledArgumentCharacteristic {
261278
ReceiverStorageCharacteristic() { this = "ReceiverStorage" }
262279

263280
override predicate getEndpoints(DataFlow::Node n) {
@@ -267,7 +284,8 @@ private class ReceiverStorageCharacteristic extends NotASinkCharacteristic {
267284
}
268285
}
269286

270-
private class StringStartsWithCharacteristic extends NotASinkCharacteristic {
287+
private class StringStartsWithCharacteristic extends NotASinkCharacteristic,
288+
OtherModeledArgumentCharacteristic {
271289
StringStartsWithCharacteristic() { this = "StringStartsWith" }
272290

273291
override predicate getEndpoints(DataFlow::Node n) {
@@ -277,15 +295,17 @@ private class StringStartsWithCharacteristic extends NotASinkCharacteristic {
277295
}
278296
}
279297

280-
private class StringEndsWithCharacteristic extends NotASinkCharacteristic {
298+
private class StringEndsWithCharacteristic extends NotASinkCharacteristic,
299+
OtherModeledArgumentCharacteristic {
281300
StringEndsWithCharacteristic() { this = "StringEndsWith" }
282301

283302
override predicate getEndpoints(DataFlow::Node n) {
284303
exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof StringOps::EndsWith)
285304
}
286305
}
287306

288-
private class StringRegExpTestCharacteristic extends NotASinkCharacteristic {
307+
private class StringRegExpTestCharacteristic extends NotASinkCharacteristic,
308+
OtherModeledArgumentCharacteristic {
289309
StringRegExpTestCharacteristic() { this = "StringRegExpTest" }
290310

291311
override predicate getEndpoints(DataFlow::Node n) {
@@ -295,23 +315,26 @@ private class StringRegExpTestCharacteristic extends NotASinkCharacteristic {
295315
}
296316
}
297317

298-
private class EventRegistrationCharacteristic extends NotASinkCharacteristic {
318+
private class EventRegistrationCharacteristic extends NotASinkCharacteristic,
319+
OtherModeledArgumentCharacteristic {
299320
EventRegistrationCharacteristic() { this = "EventRegistration" }
300321

301322
override predicate getEndpoints(DataFlow::Node n) {
302323
exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof EventRegistration)
303324
}
304325
}
305326

306-
private class EventDispatchCharacteristic extends NotASinkCharacteristic {
327+
private class EventDispatchCharacteristic extends NotASinkCharacteristic,
328+
OtherModeledArgumentCharacteristic {
307329
EventDispatchCharacteristic() { this = "EventDispatch" }
308330

309331
override predicate getEndpoints(DataFlow::Node n) {
310332
exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof EventDispatch)
311333
}
312334
}
313335

314-
private class MembershipCandidateTestCharacteristic extends NotASinkCharacteristic {
336+
private class MembershipCandidateTestCharacteristic extends NotASinkCharacteristic,
337+
OtherModeledArgumentCharacteristic {
315338
MembershipCandidateTestCharacteristic() { this = "MembershipCandidateTest" }
316339

317340
override predicate getEndpoints(DataFlow::Node n) {
@@ -321,15 +344,17 @@ private class MembershipCandidateTestCharacteristic extends NotASinkCharacterist
321344
}
322345
}
323346

324-
private class FileSystemAccessCharacteristic extends NotASinkCharacteristic {
347+
private class FileSystemAccessCharacteristic extends NotASinkCharacteristic,
348+
OtherModeledArgumentCharacteristic {
325349
FileSystemAccessCharacteristic() { this = "FileSystemAccess" }
326350

327351
override predicate getEndpoints(DataFlow::Node n) {
328352
exists(DataFlow::CallNode call | n = call.getAnArgument() | call instanceof FileSystemAccess)
329353
}
330354
}
331355

332-
private class DatabaseAccessCharacteristic extends NotASinkCharacteristic {
356+
private class DatabaseAccessCharacteristic extends NotASinkCharacteristic,
357+
OtherModeledArgumentCharacteristic {
333358
DatabaseAccessCharacteristic() { this = "DatabaseAccess" }
334359

335360
override predicate getEndpoints(DataFlow::Node n) {
@@ -344,15 +369,16 @@ private class DatabaseAccessCharacteristic extends NotASinkCharacteristic {
344369
}
345370
}
346371

347-
private class DomCharacteristic extends NotASinkCharacteristic {
372+
private class DomCharacteristic extends NotASinkCharacteristic, OtherModeledArgumentCharacteristic {
348373
DomCharacteristic() { this = "DOM" }
349374

350375
override predicate getEndpoints(DataFlow::Node n) {
351376
exists(DataFlow::CallNode call | n = call.getAnArgument() | call = DOM::domValueRef())
352377
}
353378
}
354379

355-
private class NextFunctionCallCharacteristic extends NotASinkCharacteristic {
380+
private class NextFunctionCallCharacteristic extends NotASinkCharacteristic,
381+
OtherModeledArgumentCharacteristic {
356382
NextFunctionCallCharacteristic() { this = "NextFunctionCall" }
357383

358384
override predicate getEndpoints(DataFlow::Node n) {
@@ -363,7 +389,8 @@ private class NextFunctionCallCharacteristic extends NotASinkCharacteristic {
363389
}
364390
}
365391

366-
private class DojoRequireCharacteristic extends NotASinkCharacteristic {
392+
private class DojoRequireCharacteristic extends NotASinkCharacteristic,
393+
OtherModeledArgumentCharacteristic {
367394
DojoRequireCharacteristic() { this = "DojoRequire" }
368395

369396
override predicate getEndpoints(DataFlow::Node n) {
@@ -373,7 +400,8 @@ private class DojoRequireCharacteristic extends NotASinkCharacteristic {
373400
}
374401
}
375402

376-
private class Base64ManipulationCharacteristic extends NotASinkCharacteristic {
403+
private class Base64ManipulationCharacteristic extends NotASinkCharacteristic,
404+
OtherModeledArgumentCharacteristic {
377405
Base64ManipulationCharacteristic() { this = "Base64Manipulation" }
378406

379407
override predicate getEndpoints(DataFlow::Node n) {
@@ -475,7 +503,7 @@ abstract private class StandardEndpointFilterCharacteristic extends EndpointFilt
475503
}
476504
}
477505

478-
private class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic {
506+
class IsArgumentToModeledFunctionCharacteristic extends StandardEndpointFilterCharacteristic {
479507
IsArgumentToModeledFunctionCharacteristic() { this = "argument to modeled function" }
480508

481509
override predicate getEndpoints(DataFlow::Node n) {
@@ -487,7 +515,9 @@ private class IsArgumentToModeledFunctionCharacteristic extends StandardEndpoint
487515
or
488516
CoreKnowledge::isKnownStepSrc(known)
489517
or
490-
CoreKnowledge::isOtherModeledArgument(known, _)
518+
exists(OtherModeledArgumentCharacteristic characteristic |
519+
characteristic.getEndpoints(known)
520+
)
491521
)
492522
)
493523
}

0 commit comments

Comments
 (0)