|
10 | 10 | */ |
11 | 11 |
|
12 | 12 | import javascript |
| 13 | +private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps |
13 | 14 |
|
14 | 15 | /** |
15 | 16 | * Provides classes and predicates for working with APIs defined or used in a database. |
@@ -945,16 +946,38 @@ private module Label { |
945 | 946 | /** Gets the `member` edge label for the unknown member. */ |
946 | 947 | string unknownMember() { result = "member *" } |
947 | 948 |
|
| 949 | + /** |
| 950 | + * Gets a property name referred to by the given dynamic property access, |
| 951 | + * allowing one property flow step in the process (to allow flow through imports). |
| 952 | + * |
| 953 | + * This is to support code patterns where the property name is actually constant, |
| 954 | + * but the property name has been factored into a library. |
| 955 | + */ |
| 956 | + private string getAnIndirectPropName(DataFlow::PropRef ref) { |
| 957 | + exists(DataFlow::Node pred | |
| 958 | + FlowSteps::propertyFlowStep(pred, ref.getPropertyNameExpr().flow()) and |
| 959 | + result = pred.getStringValue() |
| 960 | + ) |
| 961 | + } |
| 962 | + |
| 963 | + /** |
| 964 | + * Gets unique result of `getAnIndirectPropName` if there is one. |
| 965 | + */ |
| 966 | + private string getIndirectPropName(DataFlow::PropRef ref) { |
| 967 | + result = unique(string s | s = getAnIndirectPropName(ref)) |
| 968 | + } |
| 969 | + |
948 | 970 | /** Gets the `member` edge label for the given property reference. */ |
949 | 971 | string memberFromRef(DataFlow::PropRef pr) { |
950 | | - exists(string pn | pn = pr.getPropertyName() | |
| 972 | + exists(string pn | pn = pr.getPropertyName() or pn = getIndirectPropName(pr) | |
951 | 973 | result = member(pn) and |
952 | 974 | // only consider properties with alphanumeric(-ish) names, excluding special properties |
953 | 975 | // and properties whose names look like they are meant to be internal |
954 | 976 | pn.regexpMatch("(?!prototype$|__)[\\w_$][\\w\\-.$]*") |
955 | 977 | ) |
956 | 978 | or |
957 | 979 | not exists(pr.getPropertyName()) and |
| 980 | + not exists(getIndirectPropName(pr)) and |
958 | 981 | result = unknownMember() |
959 | 982 | } |
960 | 983 |
|
|
0 commit comments