Skip to content

Commit cfb9265

Browse files
committed
JS: Add template steps for res.locals.x
1 parent 5269933 commit cfb9265

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

javascript/ql/lib/semmle/javascript/frameworks/Express.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,10 @@ module Express {
10381038

10391039
override DataFlow::Node getTemplateParamsNode() { result = this.getArgument(1) }
10401040

1041+
override DataFlow::Node getTemplateParamForValue(string accessPath) {
1042+
result = res.(Routing::RouteHandlerInput).getValueFromAccessPath("locals." + accessPath)
1043+
}
1044+
10411045
override DataFlow::SourceNode getOutput() { result = this.getCallback(2).getParameter(1) }
10421046
}
10431047
}

javascript/ql/lib/semmle/javascript/frameworks/Templating.qll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,17 @@ module Templating {
158158
DataFlow::SourceNode getAVariableUse(string name) {
159159
result = this.getScope().getVariable(name).getAnAccess().flow()
160160
}
161+
162+
/** Gets a data flow node corresponding to a use of the given template variable within this top-level. */
163+
DataFlow::SourceNode getAnAccessPathUse(string accessPath) {
164+
result = getAVariableUse(accessPath)
165+
or
166+
exists(string varName, string suffix |
167+
accessPath = varName + "." + suffix and
168+
suffix != "" and
169+
result = AccessPath::getAReferenceTo(getAVariableUse(varName), suffix)
170+
)
171+
}
161172
}
162173

163174
/**
@@ -177,6 +188,11 @@ module Templating {
177188
/** Gets a data flow node that refers to an object whose properties become variables in the template. */
178189
DataFlow::Node getTemplateParamsNode() { result = range.getTemplateParamsNode() }
179190

191+
/** Gets a data flow node that provides the value for the template variable at the given access path. */
192+
DataFlow::Node getTemplateParamForValue(string accessPath) {
193+
result = range.getTemplateParamForValue(accessPath)
194+
}
195+
180196
/** Gets the template file instantiated here, if any. */
181197
TemplateFile getTemplateFile() {
182198
result = this.getTemplateFileNode().(TemplateFileReference).getTemplateFile()
@@ -202,6 +218,9 @@ module Templating {
202218
/** Gets a data flow node that refers to an object whose properties become variables in the template. */
203219
abstract DataFlow::Node getTemplateParamsNode();
204220

221+
/** Gets a data flow node that provides the value for the template variable at the given access path. */
222+
DataFlow::Node getTemplateParamForValue(string accessPath) { none() }
223+
205224
/**
206225
* Gets the template syntax used by this template instantiation, if known.
207226
*
@@ -224,6 +243,16 @@ module Templating {
224243
.getAVariableUse(name)
225244
)
226245
or
246+
exists(TemplateInstantiation inst, string accessPath |
247+
result.getARhs() = inst.getTemplateParamForValue(accessPath) and
248+
succ =
249+
inst.getTemplateFile()
250+
.getAnImportedFile*()
251+
.getAPlaceholder()
252+
.getInnerTopLevel()
253+
.getAnAccessPathUse(accessPath)
254+
)
255+
or
227256
exists(string prop, DataFlow::SourceNode prev |
228257
result = getTemplateInput(prev).getMember(prop) and
229258
succ = prev.getAPropertyRead(prop)

0 commit comments

Comments
 (0)