@@ -47,23 +47,39 @@ private module HandlebarsTaintSteps {
4747 exists ( DataFlow:: TypeTracker t2 | result = compiledTemplate ( t2 , compileCall ) .track ( t2 , t ) )
4848 }
4949
50- private predicate isHelperParam (
51- string helperName , DataFlow:: FunctionNode helperFunction , DataFlow:: ParameterNode param ,
50+ /**
51+ * Gets a reference to a parameter of a registered Handlebars helper.
52+ *
53+ * ```javascript
54+ * function loudHelper(text) {
55+ * return text.toUpperCase();
56+ * }
57+ *
58+ * hb.registerHelper("loud", loudHelper);
59+ * ```
60+ * In this example, `getRegisteredHelperParameter("loud", func, 0)` will bind `func` to
61+ * the `FunctionNode` representing `function loudHelper`, and return its parameter `text`.
62+ */
63+ private DataFlow:: ParameterNode getRegisteredHelperParam (
64+ string helperName , DataFlow:: FunctionNode helperFunction ,
5265 int paramIndex
5366 ) {
5467 exists ( DataFlow:: CallNode registerHelperCall |
55- registerHelperCall = any ( Handlebars:: Handlebars hb ) .getAMethodCall ( "registerHelper" ) and
68+ registerHelperCall = any ( Handlebars:: Handlebars hb ) .getAMemberCall ( "registerHelper" ) and
5669 registerHelperCall .getArgument ( 0 ) .mayHaveStringValue ( helperName ) and
5770 helperFunction = registerHelperCall .getArgument ( 1 ) .getAFunctionValue ( ) and
58- param = helperFunction .getParameter ( paramIndex )
71+ result = helperFunction .getParameter ( paramIndex )
5972 )
6073 }
6174
62- /** Holds if `call` is a block wrapped inside curly braces inside the template `templateText`. */
75+ /** Gets a `call` (which is a block wrapped inside curly braces inside the template) from `templateText`.
76+ *
77+ * For example, `getAHelperCallFromTemplate("Hello {{loud customer}}")` will return `"loud customer"`.
78+ */
6379 bindingset [ templateText]
64- predicate templateHelperParamBlock ( string templateText , string call ) {
65- call = templateText .regexpFind ( "\\{\\{[^}]+\\}\\}" , _, _) .regexpReplaceAll ( "[{}]" , "" ) .trim ( ) and
66- call .regexpMatch ( ".*\\s.*" )
80+ private string getAHelperCallFromTemplate ( string templateText ) {
81+ result = templateText .regexpFind ( "\\{\\{[^}]+\\}\\}" , _, _) .regexpReplaceAll ( "[{}]" , "" ) .trim ( ) and
82+ result .regexpMatch ( ".*\\s.*" )
6783 }
6884
6985 /**
@@ -85,7 +101,7 @@ private module HandlebarsTaintSteps {
85101 private predicate isTemplateHelperCallArg (
86102 string templateText , string helperName , int argIdx , string argVal
87103 ) {
88- exists ( string call | templateHelperParamBlock ( templateText , call ) |
104+ exists ( string call | call = getAHelperCallFromTemplate ( templateText ) |
89105 helperName = call .regexpFind ( "[^\\s]+" , 0 , _) and
90106 argIdx >= 0 and
91107 argVal = call .regexpFind ( "[^\\s]+" , argIdx + 1 , _)
@@ -126,14 +142,14 @@ private module HandlebarsTaintSteps {
126142 pred =
127143 templatingCall .getAnArgument ( ) .getALocalSource ( ) .getAPropertyWrite ( paramName ) .getRhs ( ) and
128144 isTemplateHelperCallArg ( templateText , helperName , argIdx , paramName ) and
129- isHelperParam ( helperName , helperFunction , succ , argIdx )
145+ succ = getRegisteredHelperParam ( helperName , helperFunction , argIdx )
130146 )
131147 or
132148 // When we don't have a string value, we can't be sure
133- // and will assume a step.
149+ // and we assume a step to all parameters of all helpers .
134150 not exists ( string s | compileCall .getArgument ( 0 ) .mayHaveStringValue ( s ) ) and
135- pred = templatingCall .getAnArgument ( ) .getALocalSource ( ) .getAPropertyWrite ( ) .getRhs ( ) and
136- isHelperParam ( helperName , helperFunction , succ , _)
151+ pred = templatingCall .getArgument ( 0 ) .getALocalSource ( ) .getAPropertyWrite ( ) .getRhs ( ) and
152+ succ = getRegisteredHelperParam ( helperName , helperFunction , _)
137153 )
138154 )
139155 }
0 commit comments