Skip to content

Commit 9afc1f9

Browse files
committed
split out isAdditionalXSSFlowStep components
1 parent 8531174 commit 9afc1f9

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

ql/lib/codeql/ruby/security/XSS.qll

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,7 @@ private module Shared {
122122
AssignExpr getAnAssignExpr() { result.getLeftOperand() = this.getExpr() }
123123
}
124124

125-
/**
126-
* An additional step that is preserves dataflow in the context of XSS.
127-
*/
128-
predicate isAdditionalXSSFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
125+
predicate isFlowFromLocals(DataFlow::Node node1, DataFlow::Node node2) {
129126
// node1 is a `locals` argument to a render call...
130127
exists(RenderCall call, Pair kvPair, string hashKey |
131128
call.getLocals().getAKeyValuePair() = kvPair and
@@ -154,7 +151,9 @@ private module Shared {
154151
)
155152
)
156153
)
157-
or
154+
}
155+
156+
predicate isFlowFromControllerInstanceVariable(DataFlow::Node node1, DataFlow::Node node2) {
158157
// instance variables in the controller
159158
exists(
160159
ActionControllerActionMethod action, VariableReadAccess viewVarRead, AssignExpr ae,
@@ -169,7 +168,9 @@ private module Shared {
169168
node1.asExpr().getExpr() = ae.getRightOperand() and
170169
ae.getParent+() = action
171170
)
172-
or
171+
}
172+
173+
predicate isFlowIntoHelperMethod(DataFlow::Node node1, DataFlow::Node node2) {
173174
// flow from template into controller helper method
174175
exists(
175176
ErbFile template, ActionControllerHelperMethod helperMethod,
@@ -181,13 +182,16 @@ private module Shared {
181182
helperMethodCall.getArgument(argIdx) = node1.asExpr() and
182183
helperMethod.getParameter(argIdx) = node2.asExpr().getExpr()
183184
)
184-
or
185+
}
186+
187+
predicate isFlowFromHelperMethod(DataFlow::Node node1, DataFlow::Node node2) {
185188
// flow out of controller helper method into template
186189
exists(
187190
ErbFile template, ActionControllerHelperMethod helperMethod,
188191
CfgNodes::ExprNodes::MethodCallCfgNode helperMethodCall
189192
|
190193
template = node2.getLocation().getFile() and
194+
// TODO: this is slow, x-product of helper method names and method calls
191195
helperMethod.getName() = helperMethodCall.getExpr().getMethodName() and
192196
helperMethod.getControllerClass() = getAssociatedControllerClass(template) and
193197
// `node1` is an expr node that may be returned by the helper method
@@ -196,6 +200,20 @@ private module Shared {
196200
node2.asExpr() = helperMethodCall
197201
)
198202
}
203+
204+
/**
205+
* An additional step that is preserves dataflow in the context of XSS.
206+
*/
207+
pragma[noopt]
208+
predicate isAdditionalXSSFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
209+
isFlowFromLocals(node1, node2)
210+
or
211+
isFlowFromControllerInstanceVariable(node1, node2)
212+
or
213+
isFlowIntoHelperMethod(node1, node2)
214+
or
215+
isFlowFromHelperMethod(node1, node2)
216+
}
199217
}
200218

201219
/**

0 commit comments

Comments
 (0)