@@ -47,23 +47,39 @@ private module HandlebarsTaintSteps {
47
47
exists ( DataFlow:: TypeTracker t2 | result = compiledTemplate ( t2 , compileCall ) .track ( t2 , t ) )
48
48
}
49
49
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 ,
52
65
int paramIndex
53
66
) {
54
67
exists ( DataFlow:: CallNode registerHelperCall |
55
- registerHelperCall = any ( Handlebars:: Handlebars hb ) .getAMethodCall ( "registerHelper" ) and
68
+ registerHelperCall = any ( Handlebars:: Handlebars hb ) .getAMemberCall ( "registerHelper" ) and
56
69
registerHelperCall .getArgument ( 0 ) .mayHaveStringValue ( helperName ) and
57
70
helperFunction = registerHelperCall .getArgument ( 1 ) .getAFunctionValue ( ) and
58
- param = helperFunction .getParameter ( paramIndex )
71
+ result = helperFunction .getParameter ( paramIndex )
59
72
)
60
73
}
61
74
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
+ */
63
79
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.*" )
67
83
}
68
84
69
85
/**
@@ -85,7 +101,7 @@ private module HandlebarsTaintSteps {
85
101
private predicate isTemplateHelperCallArg (
86
102
string templateText , string helperName , int argIdx , string argVal
87
103
) {
88
- exists ( string call | templateHelperParamBlock ( templateText , call ) |
104
+ exists ( string call | call = getAHelperCallFromTemplate ( templateText ) |
89
105
helperName = call .regexpFind ( "[^\\s]+" , 0 , _) and
90
106
argIdx >= 0 and
91
107
argVal = call .regexpFind ( "[^\\s]+" , argIdx + 1 , _)
@@ -126,14 +142,14 @@ private module HandlebarsTaintSteps {
126
142
pred =
127
143
templatingCall .getAnArgument ( ) .getALocalSource ( ) .getAPropertyWrite ( paramName ) .getRhs ( ) and
128
144
isTemplateHelperCallArg ( templateText , helperName , argIdx , paramName ) and
129
- isHelperParam ( helperName , helperFunction , succ , argIdx )
145
+ succ = getRegisteredHelperParam ( helperName , helperFunction , argIdx )
130
146
)
131
147
or
132
148
// 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 .
134
150
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 , _)
137
153
)
138
154
)
139
155
}
0 commit comments