Skip to content

Commit 9254df1

Browse files
committed
sanitize optionally sanitized values
1 parent 8fac3a1 commit 9254df1

File tree

6 files changed

+250
-0
lines changed

6 files changed

+250
-0
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ module DomBasedXss {
4747
prop = urlSuffixPseudoProperty()
4848
)
4949
}
50+
51+
override predicate isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) {
52+
DomBasedXss::isOptionallySanitizedEdge(pred, succ)
53+
}
5054
}
5155

5256
private string urlSuffixPseudoProperty() { result = "$UrlSuffix$" }

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,38 @@ module DomBasedXss {
302302
private class MetacharEscapeSanitizer extends Sanitizer, Shared::MetacharEscapeSanitizer { }
303303

304304
private class UriEncodingSanitizer extends Sanitizer, Shared::UriEncodingSanitizer { }
305+
306+
/**
307+
* Holds if there exists two dataflow edges to `succ`, where one edges is sanitized, and the other edge starts with `pred`.
308+
*/
309+
predicate isOptionallySanitizedEdge(DataFlow::Node pred, DataFlow::Node succ) {
310+
exists(DataFlow::CallNode sanitizer |
311+
sanitizer.getCalleeName().regexpMatch("(?i).*sanitize.*")
312+
|
313+
// sanitized = sanitize ? sanitizer(source) : source;
314+
exists(ConditionalExpr branch, Variable var, VarAccess access |
315+
branch = succ.asExpr() and access = var.getAnAccess()
316+
|
317+
branch.getABranch() = access and
318+
pred.getEnclosingExpr() = access and
319+
sanitizer = branch.getABranch().flow() and
320+
sanitizer.getAnArgument().getEnclosingExpr() = var.getAnAccess()
321+
)
322+
or
323+
// sanitized = source; if (sanitize) {sanitized = sanitizer(source)};
324+
exists(SsaPhiNode phi, SsaExplicitDefinition a, SsaDefinition b |
325+
a = phi.getAnInput().getDefinition() and
326+
b = phi.getAnInput().getDefinition() and
327+
count(phi.getAnInput()) = 2 and
328+
not a = b and
329+
sanitizer = DataFlow::valueNode(a.getDef().getSource()) and
330+
sanitizer.getAnArgument().asExpr().(VarAccess).getVariable() = b.getSourceVariable()
331+
|
332+
pred = DataFlow::ssaDefinitionNode(b) and
333+
succ = DataFlow::ssaDefinitionNode(phi)
334+
)
335+
)
336+
}
305337
}
306338

307339
/** Provides classes and predicates for the reflected XSS query. */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ module XssThroughDom {
3333
guard instanceof TypeTestGuard or
3434
guard instanceof UnsafeJQuery::PropertyPresenceSanitizer
3535
}
36+
37+
override predicate isSanitizerEdge(DataFlow::Node pred, DataFlow::Node succ) {
38+
DomBasedXss::isOptionallySanitizedEdge(pred, succ)
39+
}
3640
}
3741

3842
/**

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

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,46 @@ nodes
3636
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
3737
| nodemailer.js:13:50:13:66 | req.query.message |
3838
| nodemailer.js:13:50:13:66 | req.query.message |
39+
| optionalSanitizer.js:2:7:2:39 | target |
40+
| optionalSanitizer.js:2:16:2:32 | document.location |
41+
| optionalSanitizer.js:2:16:2:32 | document.location |
42+
| optionalSanitizer.js:2:16:2:39 | documen ... .search |
43+
| optionalSanitizer.js:6:18:6:23 | target |
44+
| optionalSanitizer.js:6:18:6:23 | target |
45+
| optionalSanitizer.js:8:7:8:22 | tainted |
46+
| optionalSanitizer.js:8:17:8:22 | target |
47+
| optionalSanitizer.js:9:18:9:24 | tainted |
48+
| optionalSanitizer.js:9:18:9:24 | tainted |
49+
| optionalSanitizer.js:15:9:15:14 | target |
50+
| optionalSanitizer.js:16:18:16:18 | x |
51+
| optionalSanitizer.js:17:20:17:20 | x |
52+
| optionalSanitizer.js:17:20:17:20 | x |
53+
| optionalSanitizer.js:26:7:26:39 | target |
54+
| optionalSanitizer.js:26:16:26:32 | document.location |
55+
| optionalSanitizer.js:26:16:26:32 | document.location |
56+
| optionalSanitizer.js:26:16:26:39 | documen ... .search |
57+
| optionalSanitizer.js:31:7:31:23 | tainted2 |
58+
| optionalSanitizer.js:31:18:31:23 | target |
59+
| optionalSanitizer.js:32:18:32:25 | tainted2 |
60+
| optionalSanitizer.js:32:18:32:25 | tainted2 |
61+
| optionalSanitizer.js:34:5:34:36 | tainted2 |
62+
| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) |
63+
| optionalSanitizer.js:34:28:34:35 | tainted2 |
64+
| optionalSanitizer.js:36:18:36:25 | tainted2 |
65+
| optionalSanitizer.js:36:18:36:25 | tainted2 |
66+
| optionalSanitizer.js:38:7:38:23 | tainted3 |
67+
| optionalSanitizer.js:38:18:38:23 | target |
68+
| optionalSanitizer.js:39:18:39:25 | tainted3 |
69+
| optionalSanitizer.js:39:18:39:25 | tainted3 |
70+
| optionalSanitizer.js:41:5:41:36 | tainted3 |
71+
| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) |
72+
| optionalSanitizer.js:41:28:41:35 | tainted3 |
73+
| optionalSanitizer.js:43:18:43:25 | tainted3 |
74+
| optionalSanitizer.js:43:18:43:25 | tainted3 |
75+
| optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
76+
| optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
77+
| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) |
78+
| optionalSanitizer.js:45:41:45:46 | target |
3979
| react-native.js:7:7:7:33 | tainted |
4080
| react-native.js:7:17:7:33 | req.param("code") |
4181
| react-native.js:7:17:7:33 | req.param("code") |
@@ -417,6 +457,44 @@ edges
417457
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
418458
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
419459
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
460+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target |
461+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target |
462+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target |
463+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target |
464+
| optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:2:16:2:39 | documen ... .search |
465+
| optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:2:16:2:39 | documen ... .search |
466+
| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target |
467+
| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted |
468+
| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted |
469+
| optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted |
470+
| optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x |
471+
| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x |
472+
| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x |
473+
| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target |
474+
| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target |
475+
| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target |
476+
| optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:26:16:26:39 | documen ... .search |
477+
| optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:26:16:26:39 | documen ... .search |
478+
| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target |
479+
| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 |
480+
| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 |
481+
| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 |
482+
| optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 |
483+
| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 |
484+
| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 |
485+
| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 |
486+
| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) |
487+
| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 |
488+
| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 |
489+
| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 |
490+
| optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 |
491+
| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 |
492+
| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 |
493+
| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 |
494+
| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) |
495+
| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
496+
| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
497+
| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) |
420498
| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted |
421499
| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted |
422500
| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted |
@@ -728,6 +806,14 @@ edges
728806
| jquery.js:7:5:7:34 | "<div i ... + "\\">" | jquery.js:2:17:2:33 | document.location | jquery.js:7:5:7:34 | "<div i ... + "\\">" | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
729807
| jquery.js:8:18:8:34 | "XSS: " + tainted | jquery.js:2:17:2:33 | document.location | jquery.js:8:18:8:34 | "XSS: " + tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
730808
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | HTML injection vulnerability due to $@. | nodemailer.js:13:50:13:66 | req.query.message | user-provided value |
809+
| optionalSanitizer.js:6:18:6:23 | target | optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:6:18:6:23 | target | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:2:16:2:32 | document.location | user-provided value |
810+
| optionalSanitizer.js:9:18:9:24 | tainted | optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:9:18:9:24 | tainted | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:2:16:2:32 | document.location | user-provided value |
811+
| optionalSanitizer.js:17:20:17:20 | x | optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:17:20:17:20 | x | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:2:16:2:32 | document.location | user-provided value |
812+
| optionalSanitizer.js:32:18:32:25 | tainted2 | optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:32:18:32:25 | tainted2 | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:26:16:26:32 | document.location | user-provided value |
813+
| optionalSanitizer.js:36:18:36:25 | tainted2 | optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:36:18:36:25 | tainted2 | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:26:16:26:32 | document.location | user-provided value |
814+
| optionalSanitizer.js:39:18:39:25 | tainted3 | optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:39:18:39:25 | tainted3 | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:26:16:26:32 | document.location | user-provided value |
815+
| optionalSanitizer.js:43:18:43:25 | tainted3 | optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:43:18:43:25 | tainted3 | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:26:16:26:32 | document.location | user-provided value |
816+
| optionalSanitizer.js:45:18:45:56 | sanitiz ... target | optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:45:18:45:56 | sanitiz ... target | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:26:16:26:32 | document.location | user-provided value |
731817
| react-native.js:8:18:8:24 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:18:8:24 | tainted | Cross-site scripting vulnerability due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
732818
| react-native.js:9:27:9:33 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:9:27:9:33 | tainted | Cross-site scripting vulnerability due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
733819
| stored-xss.js:5:20:5:52 | session ... ssion') | stored-xss.js:2:39:2:55 | document.location | stored-xss.js:5:20:5:52 | session ... ssion') | Cross-site scripting vulnerability due to $@. | stored-xss.js:2:39:2:55 | document.location | user-provided value |

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

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,46 @@ nodes
3636
| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
3737
| nodemailer.js:13:50:13:66 | req.query.message |
3838
| nodemailer.js:13:50:13:66 | req.query.message |
39+
| optionalSanitizer.js:2:7:2:39 | target |
40+
| optionalSanitizer.js:2:16:2:32 | document.location |
41+
| optionalSanitizer.js:2:16:2:32 | document.location |
42+
| optionalSanitizer.js:2:16:2:39 | documen ... .search |
43+
| optionalSanitizer.js:6:18:6:23 | target |
44+
| optionalSanitizer.js:6:18:6:23 | target |
45+
| optionalSanitizer.js:8:7:8:22 | tainted |
46+
| optionalSanitizer.js:8:17:8:22 | target |
47+
| optionalSanitizer.js:9:18:9:24 | tainted |
48+
| optionalSanitizer.js:9:18:9:24 | tainted |
49+
| optionalSanitizer.js:15:9:15:14 | target |
50+
| optionalSanitizer.js:16:18:16:18 | x |
51+
| optionalSanitizer.js:17:20:17:20 | x |
52+
| optionalSanitizer.js:17:20:17:20 | x |
53+
| optionalSanitizer.js:26:7:26:39 | target |
54+
| optionalSanitizer.js:26:16:26:32 | document.location |
55+
| optionalSanitizer.js:26:16:26:32 | document.location |
56+
| optionalSanitizer.js:26:16:26:39 | documen ... .search |
57+
| optionalSanitizer.js:31:7:31:23 | tainted2 |
58+
| optionalSanitizer.js:31:18:31:23 | target |
59+
| optionalSanitizer.js:32:18:32:25 | tainted2 |
60+
| optionalSanitizer.js:32:18:32:25 | tainted2 |
61+
| optionalSanitizer.js:34:5:34:36 | tainted2 |
62+
| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) |
63+
| optionalSanitizer.js:34:28:34:35 | tainted2 |
64+
| optionalSanitizer.js:36:18:36:25 | tainted2 |
65+
| optionalSanitizer.js:36:18:36:25 | tainted2 |
66+
| optionalSanitizer.js:38:7:38:23 | tainted3 |
67+
| optionalSanitizer.js:38:18:38:23 | target |
68+
| optionalSanitizer.js:39:18:39:25 | tainted3 |
69+
| optionalSanitizer.js:39:18:39:25 | tainted3 |
70+
| optionalSanitizer.js:41:5:41:36 | tainted3 |
71+
| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) |
72+
| optionalSanitizer.js:41:28:41:35 | tainted3 |
73+
| optionalSanitizer.js:43:18:43:25 | tainted3 |
74+
| optionalSanitizer.js:43:18:43:25 | tainted3 |
75+
| optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
76+
| optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
77+
| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) |
78+
| optionalSanitizer.js:45:41:45:46 | target |
3979
| react-native.js:7:7:7:33 | tainted |
4080
| react-native.js:7:17:7:33 | req.param("code") |
4181
| react-native.js:7:17:7:33 | req.param("code") |
@@ -421,6 +461,44 @@ edges
421461
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
422462
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
423463
| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` |
464+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target |
465+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:6:18:6:23 | target |
466+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:8:17:8:22 | target |
467+
| optionalSanitizer.js:2:7:2:39 | target | optionalSanitizer.js:15:9:15:14 | target |
468+
| optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:2:16:2:39 | documen ... .search |
469+
| optionalSanitizer.js:2:16:2:32 | document.location | optionalSanitizer.js:2:16:2:39 | documen ... .search |
470+
| optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:2:7:2:39 | target |
471+
| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted |
472+
| optionalSanitizer.js:8:7:8:22 | tainted | optionalSanitizer.js:9:18:9:24 | tainted |
473+
| optionalSanitizer.js:8:17:8:22 | target | optionalSanitizer.js:8:7:8:22 | tainted |
474+
| optionalSanitizer.js:15:9:15:14 | target | optionalSanitizer.js:16:18:16:18 | x |
475+
| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x |
476+
| optionalSanitizer.js:16:18:16:18 | x | optionalSanitizer.js:17:20:17:20 | x |
477+
| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:31:18:31:23 | target |
478+
| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:38:18:38:23 | target |
479+
| optionalSanitizer.js:26:7:26:39 | target | optionalSanitizer.js:45:41:45:46 | target |
480+
| optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:26:16:26:39 | documen ... .search |
481+
| optionalSanitizer.js:26:16:26:32 | document.location | optionalSanitizer.js:26:16:26:39 | documen ... .search |
482+
| optionalSanitizer.js:26:16:26:39 | documen ... .search | optionalSanitizer.js:26:7:26:39 | target |
483+
| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 |
484+
| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:32:18:32:25 | tainted2 |
485+
| optionalSanitizer.js:31:7:31:23 | tainted2 | optionalSanitizer.js:34:28:34:35 | tainted2 |
486+
| optionalSanitizer.js:31:18:31:23 | target | optionalSanitizer.js:31:7:31:23 | tainted2 |
487+
| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 |
488+
| optionalSanitizer.js:34:5:34:36 | tainted2 | optionalSanitizer.js:36:18:36:25 | tainted2 |
489+
| optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) | optionalSanitizer.js:34:5:34:36 | tainted2 |
490+
| optionalSanitizer.js:34:28:34:35 | tainted2 | optionalSanitizer.js:34:16:34:36 | sanitiz ... inted2) |
491+
| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 |
492+
| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:39:18:39:25 | tainted3 |
493+
| optionalSanitizer.js:38:7:38:23 | tainted3 | optionalSanitizer.js:41:28:41:35 | tainted3 |
494+
| optionalSanitizer.js:38:18:38:23 | target | optionalSanitizer.js:38:7:38:23 | tainted3 |
495+
| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 |
496+
| optionalSanitizer.js:41:5:41:36 | tainted3 | optionalSanitizer.js:43:18:43:25 | tainted3 |
497+
| optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) | optionalSanitizer.js:41:5:41:36 | tainted3 |
498+
| optionalSanitizer.js:41:28:41:35 | tainted3 | optionalSanitizer.js:41:16:41:36 | sanitiz ... inted3) |
499+
| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
500+
| optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) | optionalSanitizer.js:45:18:45:56 | sanitiz ... target |
501+
| optionalSanitizer.js:45:41:45:46 | target | optionalSanitizer.js:45:29:45:47 | sanitizeBad(target) |
424502
| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted |
425503
| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted |
426504
| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted |
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
function test() {
2+
var target = document.location.search
3+
4+
$('myId').html(sanitize ? DOMPurify.sanitize(target) : target); // OK
5+
6+
$('myId').html(target); // NOT OK
7+
8+
var tainted = target;
9+
$('myId').html(tainted); // NOT OK
10+
if (sanitize) {
11+
tainted = DOMPurify.sanitize(tainted);
12+
}
13+
$('myId').html(tainted); // OK
14+
15+
inner(target);
16+
function inner(x) {
17+
$('myId').html(x); // NOT OK
18+
if (sanitize) {
19+
x = DOMPurify.sanitize(x);
20+
}
21+
$('myId').html(x); // OK
22+
}
23+
}
24+
25+
function badSanitizer() {
26+
var target = document.location.search
27+
28+
function sanitizeBad(x) {
29+
return x; // No sanitization;
30+
}
31+
var tainted2 = target;
32+
$('myId').html(tainted2); // NOT OK
33+
if (sanitize) {
34+
tainted2 = sanitizeBad(tainted2);
35+
}
36+
$('myId').html(tainted2); // NOT OK
37+
38+
var tainted3 = target;
39+
$('myId').html(tainted3); // NOT OK
40+
if (sanitize) {
41+
tainted3 = sanitizeBad(tainted3);
42+
}
43+
$('myId').html(tainted3); // NOT OK
44+
45+
$('myId').html(sanitize ? sanitizeBad(target) : target); // NOT OK
46+
}

0 commit comments

Comments
 (0)