Skip to content

Commit 6533260

Browse files
esbenaStephan Brandauer
authored andcommitted
add more features
1 parent c4c4d28 commit 6533260

2 files changed

Lines changed: 99 additions & 9 deletions

File tree

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

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,9 @@ private newtype TEndpointFeature =
233233
TCalleeAccessPathWithStructuralInfo() or
234234
TEnclosingFunctionBody() or
235235
TCalleeAccessPathSimpleFromArgumentTraversal() or
236-
TParameterAccessPathSimpleFromArgumentTraversal()
236+
TParameterAccessPathSimpleFromArgumentTraversal() or
237+
TPropertyAccessPathSimpleFromArgumentTraversal() or
238+
TArgumentIndexFromArgumentTraversal()
237239

238240
/**
239241
* An implementation of an endpoint feature: produces feature names and values for used in ML.
@@ -438,14 +440,25 @@ private module SyntacticUtilities {
438440
string getSimpleParameterAccessPath(DataFlow::Node node) {
439441
if exists(DataFlow::CallNode call | node = call.getArgument(_))
440442
then exists(DataFlow::CallNode call, int i | node = call.getArgument(i) | result = i + "")
441-
else
442-
if exists(ObjectExpr o | o.getAProperty().getInit().getUnderlyingValue() = node.asExpr())
443-
then
444-
exists(DataFlow::PropWrite w |
445-
w.getRhs() = node and
446-
result = getSimpleParameterAccessPath(w.getBase()) + "." + getPropertyNameOrUnknown(w)
447-
)
448-
else result = "?"
443+
else result = getSimplePropertyAccessPath(node)
444+
}
445+
446+
/**
447+
* Computes a simple access path for how a user can refer to a value that appears in an (nested) object.
448+
*
449+
* Supports:
450+
* - properties of (nested) objects
451+
*
452+
* Unknown cases and property names results in `?`.
453+
*/
454+
string getSimplePropertyAccessPath(DataFlow::Node node) {
455+
if exists(ObjectExpr o | o.getAProperty().getInit().getUnderlyingValue() = node.asExpr())
456+
then
457+
exists(DataFlow::PropWrite w |
458+
w.getRhs() = node and
459+
result = getSimpleParameterAccessPath(w.getBase()) + "." + getPropertyNameOrUnknown(w)
460+
)
461+
else result = "?"
449462
}
450463

451464
/**
@@ -565,3 +578,54 @@ class ParameterAccessPathSimpleFromArgumentTraversal extends EndpointFeature,
565578
)
566579
}
567580
}
581+
582+
/**
583+
* The feature for how a callee can refer to a the endpoint that is "contained" in a some argument to a call
584+
*
585+
* "Containment" is syntactic, and currently means that the endpoint is an argument to the call, or that the endpoint is a (nested) property value of an argument.
586+
*
587+
* This feature is intended as a superior version of the `ArgumentIndexFeature`.
588+
*/
589+
class PropertyAccessPathSimpleFromArgumentTraversal extends EndpointFeature,
590+
TPropertyAccessPathSimpleFromArgumentTraversal {
591+
override string getName() { result = "PropertyAccessPathSimpleFromArgumentTraversal" }
592+
593+
private string getValueMaybe(DataFlow::Node endpoint) {
594+
exists(DataFlow::InvokeNode invk |
595+
result = SyntacticUtilities::getSimpleParameterAccessPath(endpoint) and
596+
SyntacticUtilities::getANestedInitializerValue(invk.getAnArgument()
597+
.asExpr()
598+
.getUnderlyingValue()).flow() = endpoint
599+
)
600+
}
601+
602+
override string getValue(DataFlow::Node endpoint) {
603+
if exists(this.getValueMaybe(endpoint))
604+
then result = this.getValueMaybe(endpoint)
605+
else result = ""
606+
}
607+
}
608+
609+
/**
610+
* The feature for how the index of an argument that "contains" and endpoint.
611+
*
612+
* "Containment" is syntactic, and currently means that the endpoint is an argument to the call, or that the endpoint is a (nested) property value of an argument.
613+
*
614+
* This feature is intended as a superior version of the `ArgumentIndexFeature`.
615+
*/
616+
class ArgumentIndexFromArgumentTraversal extends EndpointFeature,
617+
TArgumentIndexFromArgumentTraversal {
618+
override string getName() { result = "ArgumentIndexFromArgumentTraversal" }
619+
620+
override string getValue(DataFlow::Node endpoint) {
621+
exists(DataFlow::InvokeNode invk, DataFlow::Node arg, int i | arg = invk.getArgument(i) |
622+
result = i + "" and
623+
(
624+
invk.getAnArgument() = endpoint
625+
or
626+
SyntacticUtilities::getANestedInitializerValue(arg.asExpr().getUnderlyingValue()).flow() =
627+
endpoint
628+
)
629+
)
630+
}
631+
}

javascript/ql/experimental/adaptivethreatmodeling/test/generic_feature_testing/FeatureValue.expected

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,92 @@
1+
| test.html:2:61:2:68 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
12
| test.html:2:61:2:68 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
3+
| test.html:2:61:2:68 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
24
| test.html:2:61:2:68 | endpoint | argumentIndex | 0 |
35
| test.html:2:61:2:68 | endpoint | calleeAccessPath | |
46
| test.html:2:61:2:68 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | $event.target.files.item |
57
| test.html:2:61:2:68 | endpoint | calleeAccessPathWithStructuralInfo | |
68
| test.html:2:61:2:68 | endpoint | calleeName | item |
9+
| test.js:2:7:2:14 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
710
| test.js:2:7:2:14 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
11+
| test.js:2:7:2:14 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
812
| test.js:2:7:2:14 | endpoint | argumentIndex | 0 |
913
| test.js:2:7:2:14 | endpoint | calleeAccessPath | |
1014
| test.js:2:7:2:14 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | f |
1115
| test.js:2:7:2:14 | endpoint | calleeAccessPathWithStructuralInfo | |
1216
| test.js:2:7:2:14 | endpoint | calleeName | f |
17+
| test.js:3:11:3:18 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
1318
| test.js:3:11:3:18 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0.p |
19+
| test.js:3:11:3:18 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | 0.p |
1420
| test.js:3:11:3:18 | endpoint | calleeAccessPath | |
1521
| test.js:3:11:3:18 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | f |
1622
| test.js:3:11:3:18 | endpoint | calleeAccessPathWithStructuralInfo | |
23+
| test.js:4:15:4:22 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
1724
| test.js:4:15:4:22 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0.p.q |
25+
| test.js:4:15:4:22 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | 0.p.q |
1826
| test.js:4:15:4:22 | endpoint | calleeAccessPath | |
1927
| test.js:4:15:4:22 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | f |
2028
| test.js:4:15:4:22 | endpoint | calleeAccessPathWithStructuralInfo | |
29+
| test.js:5:9:5:16 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
2130
| test.js:5:9:5:16 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
31+
| test.js:5:9:5:16 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
2232
| test.js:5:9:5:16 | endpoint | argumentIndex | 0 |
2333
| test.js:5:9:5:16 | endpoint | calleeAccessPath | |
2434
| test.js:5:9:5:16 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | o.m |
2535
| test.js:5:9:5:16 | endpoint | calleeAccessPathWithStructuralInfo | |
2636
| test.js:5:9:5:16 | endpoint | calleeName | m |
2737
| test.js:5:9:5:16 | endpoint | receiverName | o |
38+
| test.js:6:13:6:20 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
2839
| test.js:6:13:6:20 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0.p |
40+
| test.js:6:13:6:20 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | 0.p |
2941
| test.js:6:13:6:20 | endpoint | calleeAccessPath | |
3042
| test.js:6:13:6:20 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | o.m |
3143
| test.js:6:13:6:20 | endpoint | calleeAccessPathWithStructuralInfo | |
44+
| test.js:7:17:7:24 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
3245
| test.js:7:17:7:24 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0.p.q |
46+
| test.js:7:17:7:24 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | 0.p.q |
3347
| test.js:7:17:7:24 | endpoint | calleeAccessPath | |
3448
| test.js:7:17:7:24 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | o.m |
3549
| test.js:7:17:7:24 | endpoint | calleeAccessPathWithStructuralInfo | |
50+
| test.js:8:11:8:18 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
3651
| test.js:8:11:8:18 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | ? |
52+
| test.js:8:11:8:18 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
3753
| test.js:8:11:8:18 | endpoint | calleeAccessPath | |
3854
| test.js:8:11:8:18 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | F |
3955
| test.js:8:11:8:18 | endpoint | calleeAccessPathWithStructuralInfo | |
56+
| test.js:9:17:9:24 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
4057
| test.js:9:17:9:24 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
58+
| test.js:9:17:9:24 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
4159
| test.js:9:17:9:24 | endpoint | argumentIndex | 0 |
4260
| test.js:9:17:9:24 | endpoint | calleeAccessPath | |
4361
| test.js:9:17:9:24 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | o.m().m().m |
4462
| test.js:9:17:9:24 | endpoint | calleeAccessPathWithStructuralInfo | |
4563
| test.js:9:17:9:24 | endpoint | calleeName | m |
64+
| test.js:10:9:10:16 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
4665
| test.js:10:9:10:16 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
66+
| test.js:10:9:10:16 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
4767
| test.js:10:9:10:16 | endpoint | argumentIndex | 0 |
4868
| test.js:10:9:10:16 | endpoint | calleeAccessPath | |
4969
| test.js:10:9:10:16 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | f() |
5070
| test.js:10:9:10:16 | endpoint | calleeAccessPathWithStructuralInfo | |
71+
| test.js:11:12:11:19 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
5172
| test.js:11:12:11:19 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
73+
| test.js:11:12:11:19 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
5274
| test.js:11:12:11:19 | endpoint | argumentIndex | 0 |
5375
| test.js:11:12:11:19 | endpoint | calleeAccessPath | |
5476
| test.js:11:12:11:19 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | o.?.m |
5577
| test.js:11:12:11:19 | endpoint | calleeAccessPathWithStructuralInfo | |
5678
| test.js:11:12:11:19 | endpoint | calleeName | m |
79+
| test.js:12:16:12:23 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
5780
| test.js:12:16:12:23 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
81+
| test.js:12:16:12:23 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
5882
| test.js:12:16:12:23 | endpoint | argumentIndex | 0 |
5983
| test.js:12:16:12:23 | endpoint | calleeAccessPath | |
6084
| test.js:12:16:12:23 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | o.m.?.p.m |
6185
| test.js:12:16:12:23 | endpoint | calleeAccessPathWithStructuralInfo | |
6286
| test.js:12:16:12:23 | endpoint | calleeName | m |
87+
| test.js:13:15:13:22 | endpoint | ArgumentIndexFromArgumentTraversal | 0 |
6388
| test.js:13:15:13:22 | endpoint | ParameterAccessPathSimpleFromArgumentTraversal | 0 |
89+
| test.js:13:15:13:22 | endpoint | PropertyAccessPathSimpleFromArgumentTraversal | |
6490
| test.js:13:15:13:22 | endpoint | argumentIndex | 0 |
6591
| test.js:13:15:13:22 | endpoint | calleeAccessPath | |
6692
| test.js:13:15:13:22 | endpoint | calleeAccessPathSimpleFromArgumentTraversal | (await p) |

0 commit comments

Comments
 (0)