diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll index b4a9002b28f..e9411d367a2 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll @@ -236,7 +236,8 @@ private newtype TEndpointFeature = TInputAccessPathFromCallee() or TInputArgumentIndex() or TContextFunctionInterfaces() or - TContextSurroundingFunctionParameters() + TContextSurroundingFunctionParameters() or + TAssignedToPropName() /** * An implementation of an endpoint feature: produces feature names and values for used in ML. @@ -472,6 +473,25 @@ class ContextSurroundingFunctionParameters extends EndpointFeature, } } +/** + * The feature that gives the name an endpoint is assigned to (if any). + * + * ### Example + * ```javascript + * const div = document.createElement('div'); + * div.innerHTML = endpoint; // feature value is 'innerHTML' + * ``` + */ +class AssignedToPropName extends EndpointFeature, TAssignedToPropName { + override string getName() { result = "assignedToPropName" } + + override string getValue(DataFlow::Node endpoint) { + exists(DataFlow::PropWrite w | w.getRhs().asExpr().getUnderlyingValue().flow() = endpoint | + result = w.getPropertyName() + ) + } +} + /** * The feature for the imports used in the callee of an invocation. *