Skip to content

Commit 65a018c

Browse files
committed
use flow labels to avoid dual configurations
1 parent 8d2ae13 commit 65a018c

File tree

4 files changed

+59
-1312
lines changed

4 files changed

+59
-1312
lines changed

javascript/ql/src/Security/CWE-079/ExceptionXss.ql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ import DataFlow::PathGraph
1919
from
2020
Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
2121
where
22-
cfg.hasFlowPath(source, sink) and
23-
not any(ConfigurationNoException c).hasFlow(source.getNode(), sink.getNode())
22+
cfg.hasFlowPath(source, sink)
2423
select sink.getNode(), source, sink,
2524
sink.getNode().(Sink).getVulnerabilityKind() + " vulnerability due to $@.", source.getNode(),
2625
"user-provided value"

javascript/ql/src/semmle/javascript/security/dataflow/ExceptionXss.qll

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,6 @@ module ExceptionXss {
3333
not node = any(DataFlow::InvokeNode call | exists(call.getACallee())).getAnArgument()
3434
or
3535
node.asExpr().getEnclosingStmt() instanceof ThrowStmt
36-
or
37-
// TODO: Do some flow label for deeply tainted objects?
38-
exists(DataFlow::ObjectLiteralNode obj |
39-
obj.asExpr().(ObjectExpr).getAProperty().getInit() = node.asExpr() and
40-
canThrowSensitiveInformation(obj)
41-
)
42-
or
43-
exists(DataFlow::ArrayCreationNode arr |
44-
arr.getAnElement() = node and
45-
canThrowSensitiveInformation(arr)
46-
)
4736
}
4837

4938
TryStmt getEnclosingTryStmt(Stmt stmt) {
@@ -52,48 +41,39 @@ module ExceptionXss {
5241
stmt.getParentStmt+() = mid.getBody() and mid.getParentStmt+() = result.getBody()
5342
)
5443
}
44+
45+
class NotYetThrown extends DataFlow::FlowLabel {
46+
NotYetThrown() { this = "NotYetThrown" }
47+
}
5548

5649
/**
5750
* A taint-tracking configuration for reasoning about XSS with possible exceptional flow.
5851
*/
59-
abstract class BaseConfiguration extends TaintTracking::Configuration {
60-
BaseConfiguration() { this = "ExceptionXss" or this = "ExceptionXssNoException" }
52+
class Configuration extends TaintTracking::Configuration {
53+
Configuration() { this = "ExceptionXss"}
6154

62-
override predicate isSource(DataFlow::Node source) { source instanceof Source }
63-
64-
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
55+
override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
56+
source instanceof Source and label instanceof NotYetThrown
57+
}
58+
59+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
60+
sink instanceof Sink and label.isDataOrTaint()
61+
}
6562

6663
override predicate isSanitizer(DataFlow::Node node) {
6764
super.isSanitizer(node) or
6865
node instanceof Sanitizer
6966
}
7067

71-
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
68+
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl) {
69+
this.isAdditionalFlowStep(pred, succ) and inlbl instanceof NotYetThrown and outlbl instanceof NotYetThrown
70+
or
71+
inlbl instanceof NotYetThrown and outlbl.isTaint() and
7272
succ = getExceptionalSuccssor(pred) and
73-
(
74-
canThrowSensitiveInformation(pred)
75-
or
76-
pred = any(DataFlow::FunctionNode func).getExceptionalReturn()
77-
)
78-
}
79-
}
80-
81-
/**
82-
* Instantiation of BaseConfiguration.
83-
*/
84-
class Configuration extends BaseConfiguration {
85-
Configuration() { this = "ExceptionXss" }
86-
}
87-
88-
/**
89-
* Same as configuration, except that all additional exceptional flows has been removed.
90-
*/
91-
class ConfigurationNoException extends BaseConfiguration {
92-
ConfigurationNoException() { this = "ExceptionXssNoException" }
93-
94-
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
95-
super.isAdditionalTaintStep(pred, succ) and
96-
not succ = getExceptionalSuccssor(pred)
73+
canThrowSensitiveInformation(pred)
74+
or
75+
inlbl instanceof NotYetThrown and outlbl instanceof NotYetThrown and
76+
exists(DataFlow::PropWrite write | write.getRhs() = pred and write.getBase() = succ)
9777
}
9878
}
9979
}

0 commit comments

Comments
 (0)