Skip to content

Commit 93aa279

Browse files
author
Stephan Brandauer
committed
documentation for new feature
1 parent 25db666 commit 93aa279

3 files changed

Lines changed: 221 additions & 123 deletions

File tree

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

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ private newtype TEndpointFeature =
231231
TCalleeAccessPathWithStructuralInfo() or
232232
TEnclosingFunctionBody() or
233233
TFileImports() or
234+
TCalleeImports() or
234235
TCalleeFlexibleAccessPath() or
235236
TInputAccessPathFromCallee() or
236237
TInputArgumentIndex()
@@ -411,7 +412,21 @@ class EnclosingFunctionBody extends EndpointFeature, TEnclosingFunctionBody {
411412
}
412413
}
413414

414-
/** The feature for the imports defined in the file containing an endpoint. */
415+
/**
416+
* The feature for the imports defined in the file containing an endpoint.
417+
*
418+
* ### Example
419+
*
420+
* ```javascript
421+
* import { findOne } from 'mongoose';
422+
* import * as _ from 'lodash';
423+
* const pg = require('pg');
424+
*
425+
* // ...
426+
* ```
427+
*
428+
* In this file, all endpoints will have the value `lodash mongoose pg` for the feature `fileImports`.
429+
*/
415430
class FileImports extends EndpointFeature, TFileImports {
416431
override string getName() { result = "fileImports" }
417432

@@ -425,6 +440,28 @@ class FileImports extends EndpointFeature, TFileImports {
425440
}
426441
}
427442

443+
class CalleeImports extends EndpointFeature, TCalleeImports {
444+
override string getName() { result = "calleeImports" }
445+
446+
override string getValue(DataFlow::Node endpoint) {
447+
not result = SyntacticUtilities::getUnknownSymbol() and
448+
exists(DataFlow::InvokeNode invk |
449+
(
450+
invk.getAnArgument() = endpoint or
451+
SyntacticUtilities::getANestedInitializerValue(invk.getAnArgument()
452+
.asExpr()
453+
.getUnderlyingValue()).flow() = endpoint
454+
) and
455+
result =
456+
concat(string importPath |
457+
importPath = SyntacticUtilities::getCalleeImportPath(invk.getCalleeNode())
458+
|
459+
importPath, " " order by importPath
460+
)
461+
)
462+
}
463+
}
464+
428465
/**
429466
* Syntactic utilities for feature value computation.
430467
*/
@@ -476,6 +513,31 @@ private module SyntacticUtilities {
476513
else result = getUnknownSymbol()
477514
}
478515

516+
/**
517+
* Gets the imported package path that this node depends on, if any.
518+
*
519+
* Otherwise, returns '?'.
520+
*
521+
* XXX Be careful with using this in your features, as it might teach the model
522+
* a fixed list of "dangerous" libraries that could lead to bad generalization.
523+
*/
524+
string getCalleeImportPath(DataFlow::Node node) {
525+
exists(DataFlow::Node src | src = node.getALocalSource() |
526+
if src instanceof DataFlow::ModuleImportNode
527+
then result = src.(DataFlow::ModuleImportNode).getPath()
528+
else
529+
if src instanceof DataFlow::PropRead
530+
then result = getCalleeImportPath(src.(DataFlow::PropRead).getBase())
531+
else
532+
if src instanceof DataFlow::InvokeNode
533+
then result = getCalleeImportPath(src.(DataFlow::InvokeNode).getCalleeNode())
534+
else
535+
if src.asExpr() instanceof AwaitExpr
536+
then result = getCalleeImportPath(src.asExpr().(AwaitExpr).getOperand().flow())
537+
else result = getUnknownSymbol()
538+
)
539+
}
540+
479541
/**
480542
* Computes a simple access path for a node.
481543
*

0 commit comments

Comments
 (0)