Skip to content

Commit 0fdeeba

Browse files
committed
C#: Re-refactor Xss to use the new API.
1 parent 94e0828 commit 0fdeeba

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ private import semmle.code.csharp.dataflow.TaintTracking2
1818
*/
1919
predicate xssFlow(XssNode source, XssNode sink, string message) {
2020
// standard taint-tracking
21-
exists(
22-
TaintTrackingConfiguration c, DataFlow2::PathNode sourceNode, DataFlow2::PathNode sinkNode
23-
|
21+
exists(XssTracking::PathNode sourceNode, XssTracking::PathNode sinkNode |
2422
sourceNode = source.asDataFlowNode() and
2523
sinkNode = sink.asDataFlowNode() and
26-
c.hasFlowPath(sourceNode, sinkNode) and
24+
XssTracking::flowPath(sourceNode, sinkNode) and
2725
message =
2826
"is written to HTML or JavaScript" +
2927
any(string explanation |
@@ -45,7 +43,7 @@ predicate xssFlow(XssNode source, XssNode sink, string message) {
4543
module PathGraph {
4644
/** Holds if `(pred,succ)` is an edge in the graph of data flow path explanations. */
4745
query predicate edges(XssNode pred, XssNode succ) {
48-
exists(DataFlow2::PathNode a, DataFlow2::PathNode b | DataFlow2::PathGraph::edges(a, b) |
46+
exists(XssTracking::PathNode a, XssTracking::PathNode b | XssTracking::PathGraph::edges(a, b) |
4947
pred.asDataFlowNode() = a and
5048
succ.asDataFlowNode() = b
5149
)
@@ -56,7 +54,7 @@ module PathGraph {
5654

5755
/** Holds if `n` is a node in the graph of data flow path explanations. */
5856
query predicate nodes(XssNode n, string key, string val) {
59-
DataFlow2::PathGraph::nodes(n.asDataFlowNode(), key, val)
57+
XssTracking::PathGraph::nodes(n.asDataFlowNode(), key, val)
6058
or
6159
xssFlow(n, n, _) and
6260
key = "semmle.label" and
@@ -69,13 +67,13 @@ module PathGraph {
6967
* `ret -> out` is summarized as the edge `arg -> out`.
7068
*/
7169
query predicate subpaths(XssNode arg, XssNode par, XssNode ret, XssNode out) {
72-
DataFlow2::PathGraph::subpaths(arg.asDataFlowNode(), par.asDataFlowNode(), ret.asDataFlowNode(),
73-
out.asDataFlowNode())
70+
XssTracking::PathGraph::subpaths(arg.asDataFlowNode(), par.asDataFlowNode(),
71+
ret.asDataFlowNode(), out.asDataFlowNode())
7472
}
7573
}
7674

7775
private newtype TXssNode =
78-
TXssDataFlowNode(DataFlow2::PathNode node) or
76+
TXssDataFlowNode(XssTracking::PathNode node) or
7977
TXssAspNode(AspInlineMember m)
8078

8179
/**
@@ -90,21 +88,25 @@ class XssNode extends TXssNode {
9088
/** Gets the location of this node. */
9189
Location getLocation() { none() }
9290

93-
/** Gets the data flow node corresponding to this node, if any. */
94-
DataFlow2::PathNode asDataFlowNode() { result = this.(XssDataFlowNode).getDataFlowNode() }
91+
/**
92+
* Gets the data flow node corresponding to this node, if any.
93+
*/
94+
XssTracking::PathNode asDataFlowNode() { result = this.(XssDataFlowNode).getDataFlowNode() }
9595

9696
/** Gets the ASP inline code element corresponding to this node, if any. */
9797
AspInlineMember asAspInlineMember() { result = this.(XssAspNode).getAspInlineMember() }
9898
}
9999

100-
/** A data flow node, viewed as an XSS flow node. */
100+
/**
101+
* A data flow node, viewed as an XSS flow node.
102+
*/
101103
class XssDataFlowNode extends TXssDataFlowNode, XssNode {
102-
DataFlow2::PathNode node;
104+
XssTracking::PathNode node;
103105

104106
XssDataFlowNode() { this = TXssDataFlowNode(node) }
105107

106108
/** Gets the data flow node corresponding to this node. */
107-
DataFlow2::PathNode getDataFlowNode() { result = node }
109+
XssTracking::PathNode getDataFlowNode() { result = node }
108110

109111
override string toString() { result = node.toString() }
110112

@@ -136,9 +138,11 @@ abstract class Source extends DataFlow::Node { }
136138
abstract class Sanitizer extends DataFlow::ExprNode { }
137139

138140
/**
141+
* DEPRECATED: Use `XssTracking` instead.
142+
*
139143
* A taint-tracking configuration for cross-site scripting (XSS) vulnerabilities.
140144
*/
141-
class TaintTrackingConfiguration extends TaintTracking2::Configuration {
145+
deprecated class TaintTrackingConfiguration extends TaintTracking2::Configuration {
142146
TaintTrackingConfiguration() { this = "XSSDataFlowConfiguration" }
143147

144148
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -148,6 +152,29 @@ class TaintTrackingConfiguration extends TaintTracking2::Configuration {
148152
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
149153
}
150154

155+
/**
156+
* A taint-tracking configuration for cross-site scripting (XSS) vulnerabilities.
157+
*/
158+
module XssTrackingConfig implements DataFlow::ConfigSig {
159+
/**
160+
* Holds if `source` is a relevant data flow source.
161+
*/
162+
predicate isSource(DataFlow::Node source) { source instanceof Source }
163+
164+
/**
165+
* Holds if `sink` is a relevant data flow sink.
166+
*/
167+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
168+
169+
/**
170+
* Holds if data flow through `node` is prohibited. This completely removes
171+
* `node` from the data flow graph.
172+
*/
173+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
174+
}
175+
176+
module XssTracking = TaintTracking::Global<XssTrackingConfig>;
177+
151178
/** A source of remote user input. */
152179
private class RemoteSource extends Source instanceof RemoteFlowSource { }
153180

csharp/ql/src/Security Features/CWE-079/StoredXSS.ql

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,21 @@ import csharp
1616
import semmle.code.csharp.security.dataflow.flowsources.Stored
1717
import semmle.code.csharp.security.dataflow.XSSQuery
1818
import semmle.code.csharp.security.dataflow.XSSSinks
19-
import semmle.code.csharp.dataflow.DataFlow2
20-
import DataFlow2::PathGraph
19+
import StoredXss::PathGraph
2120

22-
class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration {
23-
override predicate isSource(DataFlow2::Node source) { source instanceof StoredFlowSource }
21+
module StoredXssTrackingConfig implements DataFlow::ConfigSig {
22+
predicate isSource(DataFlow::Node source) { source instanceof StoredFlowSource }
23+
24+
predicate isSink = XssTrackingConfig::isSink/1;
25+
26+
predicate isBarrier = XssTrackingConfig::isBarrier/1;
2427
}
2528

26-
from
27-
StoredTaintTrackingConfiguration c, DataFlow2::PathNode source, DataFlow2::PathNode sink,
28-
string explanation
29+
module StoredXss = TaintTracking::Global<StoredXssTrackingConfig>;
30+
31+
from StoredXss::PathNode source, StoredXss::PathNode sink, string explanation
2932
where
30-
c.hasFlowPath(source, sink) and
33+
StoredXss::flowPath(source, sink) and
3134
if exists(sink.getNode().(Sink).explanation())
3235
then explanation = " (" + sink.getNode().(Sink).explanation() + ")"
3336
else explanation = ""

0 commit comments

Comments
 (0)