Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5f05232

Browse files
committed
JS: Port StoredXss
1 parent 46b90e5 commit 5f05232

4 files changed

Lines changed: 90 additions & 51 deletions

File tree

javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssCustomizations.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ module StoredXss {
2121
/** A sanitizer for stored XSS vulnerabilities. */
2222
abstract class Sanitizer extends Shared::Sanitizer { }
2323

24+
/**
25+
* A barrier guard for stored XSS.
26+
*/
27+
abstract class BarrierGuard extends DataFlow::Node {
28+
/**
29+
* Holds if this node acts as a barrier for data flow, blocking further flow from `e` if `this` evaluates to `outcome`.
30+
*/
31+
predicate blocksExpr(boolean outcome, Expr e) { none() }
32+
}
33+
34+
/** A subclass of `BarrierGuard` that is used for backward compatibility with the old data flow library. */
35+
abstract class BarrierGuardLegacy extends BarrierGuard, TaintTracking::SanitizerGuardNode {
36+
override predicate sanitizes(boolean outcome, Expr e) { this.blocksExpr(outcome, e) }
37+
}
38+
2439
/** An arbitrary XSS sink, considered as a flow sink for stored XSS. */
2540
private class AnySink extends Sink {
2641
AnySink() { this instanceof Shared::Sink }

javascript/ql/lib/semmle/javascript/security/dataflow/StoredXssQuery.qll

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,25 @@ import StoredXssCustomizations::StoredXss
88
private import Xss::Shared as Shared
99

1010
/**
11-
* A taint-tracking configuration for reasoning about XSS.
11+
* A taint-tracking configuration for reasoning about stored XSS.
1212
*/
13-
class Configuration extends TaintTracking::Configuration {
13+
module StoredXssConfig implements DataFlow::ConfigSig {
14+
predicate isSource(DataFlow::Node source) { source instanceof Source }
15+
16+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
17+
18+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
19+
}
20+
21+
/**
22+
* Taint-tracking for reasoning about stored XSS.
23+
*/
24+
module StoredXssFlow = TaintTracking::Global<StoredXssConfig>;
25+
26+
/**
27+
* DEPRECATED. Use the `StoredXssFlow` module instead.
28+
*/
29+
deprecated class Configuration extends TaintTracking::Configuration {
1430
Configuration() { this = "StoredXss" }
1531

1632
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -28,11 +44,10 @@ class Configuration extends TaintTracking::Configuration {
2844
}
2945
}
3046

31-
private class QuoteGuard extends TaintTracking::SanitizerGuardNode, Shared::QuoteGuard {
47+
private class QuoteGuard extends Shared::QuoteGuard {
3248
QuoteGuard() { this = this }
3349
}
3450

35-
private class ContainsHtmlGuard extends TaintTracking::SanitizerGuardNode, Shared::ContainsHtmlGuard
36-
{
51+
private class ContainsHtmlGuard extends Shared::ContainsHtmlGuard {
3752
ContainsHtmlGuard() { this = this }
3853
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414

1515
import javascript
1616
import semmle.javascript.security.dataflow.StoredXssQuery
17-
import DataFlow::PathGraph
17+
import StoredXssFlow::PathGraph
1818

19-
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
20-
where cfg.hasFlowPath(source, sink)
19+
from StoredXssFlow::PathNode source, StoredXssFlow::PathNode sink
20+
where StoredXssFlow::flowPath(source, sink)
2121
select sink.getNode(), source, sink, "Stored cross-site scripting vulnerability due to $@.",
2222
source.getNode(), "stored value"

javascript/ql/test/query-tests/Security/CWE-079/StoredXss/StoredXss.expected

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,64 @@
1-
nodes
2-
| xss-through-filenames.js:7:43:7:48 | files1 |
3-
| xss-through-filenames.js:7:43:7:48 | files1 |
4-
| xss-through-filenames.js:8:18:8:23 | files1 |
5-
| xss-through-filenames.js:8:18:8:23 | files1 |
6-
| xss-through-filenames.js:25:43:25:48 | files1 |
7-
| xss-through-filenames.js:25:43:25:48 | files1 |
8-
| xss-through-filenames.js:26:19:26:24 | files1 |
9-
| xss-through-filenames.js:26:19:26:24 | files1 |
10-
| xss-through-filenames.js:29:13:29:23 | files2 |
11-
| xss-through-filenames.js:29:22:29:23 | [] |
12-
| xss-through-filenames.js:30:9:30:14 | files1 |
13-
| xss-through-filenames.js:30:34:30:37 | file |
14-
| xss-through-filenames.js:31:25:31:28 | file |
15-
| xss-through-filenames.js:33:19:33:24 | files2 |
16-
| xss-through-filenames.js:33:19:33:24 | files2 |
17-
| xss-through-filenames.js:35:13:35:35 | files3 |
18-
| xss-through-filenames.js:35:22:35:35 | format(files2) |
19-
| xss-through-filenames.js:35:29:35:34 | files2 |
20-
| xss-through-filenames.js:37:19:37:24 | files3 |
21-
| xss-through-filenames.js:37:19:37:24 | files3 |
22-
| xss-through-torrent.js:6:6:6:24 | name |
23-
| xss-through-torrent.js:6:13:6:24 | torrent.name |
24-
| xss-through-torrent.js:6:13:6:24 | torrent.name |
25-
| xss-through-torrent.js:7:11:7:14 | name |
26-
| xss-through-torrent.js:7:11:7:14 | name |
271
edges
282
| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 |
29-
| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 |
30-
| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 |
31-
| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 |
32-
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 |
33-
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 |
3+
| xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:19:9:19:14 | files2 |
4+
| xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] |
5+
| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) |
6+
| xss-through-filenames.js:19:9:19:14 | files2 | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] |
7+
| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) |
8+
| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] |
9+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 |
10+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | xss-through-filenames.js:22:16:22:21 | files3 |
11+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 |
12+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | xss-through-filenames.js:22:16:22:21 | files3 |
13+
| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') |
14+
| xss-through-filenames.js:22:16:22:21 | files3 | xss-through-filenames.js:22:16:22:30 | files3.join('') |
3415
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 |
35-
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 |
36-
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 |
3716
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 |
38-
| xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:33:19:33:24 | files2 |
39-
| xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:33:19:33:24 | files2 |
40-
| xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:35:29:35:34 | files2 |
41-
| xss-through-filenames.js:29:22:29:23 | [] | xss-through-filenames.js:29:13:29:23 | files2 |
42-
| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:30:34:30:37 | file |
43-
| xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:25:31:28 | file |
44-
| xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:29:22:29:23 | [] |
45-
| xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 |
17+
| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 |
18+
| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 |
19+
| xss-through-filenames.js:30:9:30:14 | files1 | xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] |
20+
| xss-through-filenames.js:33:19:33:24 | files2 | xss-through-filenames.js:35:29:35:34 | files2 |
21+
| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] |
4622
| xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 |
4723
| xss-through-filenames.js:35:22:35:35 | format(files2) | xss-through-filenames.js:35:13:35:35 | files3 |
24+
| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 |
4825
| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:35:22:35:35 | format(files2) |
26+
| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] |
27+
| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:35:22:35:35 | format(files2) |
4928
| xss-through-torrent.js:6:6:6:24 | name | xss-through-torrent.js:7:11:7:14 | name |
50-
| xss-through-torrent.js:6:6:6:24 | name | xss-through-torrent.js:7:11:7:14 | name |
51-
| xss-through-torrent.js:6:13:6:24 | torrent.name | xss-through-torrent.js:6:6:6:24 | name |
5229
| xss-through-torrent.js:6:13:6:24 | torrent.name | xss-through-torrent.js:6:6:6:24 | name |
30+
nodes
31+
| xss-through-filenames.js:7:43:7:48 | files1 | semmle.label | files1 |
32+
| xss-through-filenames.js:8:18:8:23 | files1 | semmle.label | files1 |
33+
| xss-through-filenames.js:17:21:17:26 | files2 | semmle.label | files2 |
34+
| xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] |
35+
| xss-through-filenames.js:19:9:19:14 | files2 | semmle.label | files2 |
36+
| xss-through-filenames.js:19:9:19:14 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] |
37+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | semmle.label | files2.sort(sort) |
38+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) | semmle.label | files2.sort(sort) |
39+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | semmle.label | files2.sort(sort) [ArrayElement] |
40+
| xss-through-filenames.js:19:9:19:25 | files2.sort(sort) [ArrayElement] | semmle.label | files2.sort(sort) [ArrayElement] |
41+
| xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 |
42+
| xss-through-filenames.js:22:16:22:21 | files3 | semmle.label | files3 |
43+
| xss-through-filenames.js:22:16:22:30 | files3.join('') | semmle.label | files3.join('') |
44+
| xss-through-filenames.js:22:16:22:30 | files3.join('') | semmle.label | files3.join('') |
45+
| xss-through-filenames.js:25:43:25:48 | files1 | semmle.label | files1 |
46+
| xss-through-filenames.js:26:19:26:24 | files1 | semmle.label | files1 |
47+
| xss-through-filenames.js:30:9:30:14 | files1 | semmle.label | files1 |
48+
| xss-through-filenames.js:33:19:33:24 | files2 | semmle.label | files2 |
49+
| xss-through-filenames.js:33:19:33:24 | files2 | semmle.label | files2 |
50+
| xss-through-filenames.js:33:19:33:24 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] |
51+
| xss-through-filenames.js:35:13:35:35 | files3 | semmle.label | files3 |
52+
| xss-through-filenames.js:35:22:35:35 | format(files2) | semmle.label | format(files2) |
53+
| xss-through-filenames.js:35:29:35:34 | files2 | semmle.label | files2 |
54+
| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | semmle.label | files2 [ArrayElement] |
55+
| xss-through-filenames.js:37:19:37:24 | files3 | semmle.label | files3 |
56+
| xss-through-torrent.js:6:6:6:24 | name | semmle.label | name |
57+
| xss-through-torrent.js:6:13:6:24 | torrent.name | semmle.label | torrent.name |
58+
| xss-through-torrent.js:7:11:7:14 | name | semmle.label | name |
59+
subpaths
60+
| xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:17:21:17:26 | files2 | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) |
61+
| xss-through-filenames.js:35:29:35:34 | files2 [ArrayElement] | xss-through-filenames.js:17:21:17:26 | files2 [ArrayElement] | xss-through-filenames.js:22:16:22:30 | files3.join('') | xss-through-filenames.js:35:22:35:35 | format(files2) |
5362
#select
5463
| xss-through-filenames.js:8:18:8:23 | files1 | xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | Stored cross-site scripting vulnerability due to $@. | xss-through-filenames.js:7:43:7:48 | files1 | stored value |
5564
| xss-through-filenames.js:26:19:26:24 | files1 | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | Stored cross-site scripting vulnerability due to $@. | xss-through-filenames.js:25:43:25:48 | files1 | stored value |

0 commit comments

Comments
 (0)