|
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