Skip to content

Commit 13fae22

Browse files
authored
Merge branch 'main' into patch-1
2 parents c7b4133 + f97cc9e commit 13fae22

File tree

16 files changed

+93
-31
lines changed

16 files changed

+93
-31
lines changed

javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,19 @@ module TaintTracking {
11261126
)
11271127
}
11281128

1129+
/** A test for the value of `typeof x`, restricting the potential types of `x`. */
1130+
predicate isStringTypeGuard(EqualityTest test, Expr operand, boolean polarity) {
1131+
exists(TypeofTag tag | TaintTracking::isTypeofGuard(test, operand, tag) |
1132+
// typeof x === "string" sanitizes `x` when it evaluates to false
1133+
tag = "string" and
1134+
polarity = test.getPolarity().booleanNot()
1135+
or
1136+
// typeof x === "object" sanitizes `x` when it evaluates to true
1137+
tag != "string" and
1138+
polarity = test.getPolarity()
1139+
)
1140+
}
1141+
11291142
/** Holds if `guard` is a test that checks if `operand` is a number. */
11301143
predicate isNumberGuard(DataFlow::Node guard, Expr operand, boolean polarity) {
11311144
exists(DataFlow::CallNode isNaN |

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,18 @@ module UnsafeHtmlConstruction {
180180

181181
override string describe() { result = "Markdown rendering" }
182182
}
183+
184+
/** A test for the value of `typeof x`, restricting the potential types of `x`. */
185+
class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
186+
override EqualityTest astNode;
187+
Expr operand;
188+
boolean polarity;
189+
190+
TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) }
191+
192+
override predicate sanitizes(boolean outcome, Expr e) {
193+
polarity = outcome and
194+
e = operand
195+
}
196+
}
183197
}

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

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55

66
import javascript
7-
private import semmle.javascript.dataflow.InferredTypes
87
private import XssThroughDomCustomizations::XssThroughDom
98
private import semmle.javascript.security.dataflow.DomBasedXssCustomizations
109
private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin as UnsafeJQuery
@@ -52,27 +51,13 @@ class Configuration extends TaintTracking::Configuration {
5251
}
5352
}
5453

55-
/**
56-
* A test of form `typeof x === "something"`, preventing `x` from being a string in some cases.
57-
*
58-
* This sanitizer helps prune infeasible paths in type-overloaded functions.
59-
*/
54+
/** A test for the value of `typeof x`, restricting the potential types of `x`. */
6055
class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode {
6156
override EqualityTest astNode;
6257
Expr operand;
6358
boolean polarity;
6459

65-
TypeTestGuard() {
66-
exists(TypeofTag tag | TaintTracking::isTypeofGuard(astNode, operand, tag) |
67-
// typeof x === "string" sanitizes `x` when it evaluates to false
68-
tag = "string" and
69-
polarity = astNode.getPolarity().booleanNot()
70-
or
71-
// typeof x === "object" sanitizes `x` when it evaluates to true
72-
tag != "string" and
73-
polarity = astNode.getPolarity()
74-
)
75-
}
60+
TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) }
7661

7762
override predicate sanitizes(boolean outcome, Expr e) {
7863
polarity = outcome and

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ nodes
4646
| main.js:66:35:66:41 | attrVal |
4747
| main.js:67:63:67:69 | attrVal |
4848
| main.js:67:63:67:69 | attrVal |
49+
| main.js:79:34:79:36 | val |
50+
| main.js:79:34:79:36 | val |
51+
| main.js:81:35:81:37 | val |
52+
| main.js:81:35:81:37 | val |
4953
| typed.ts:1:39:1:39 | s |
5054
| typed.ts:1:39:1:39 | s |
5155
| typed.ts:2:29:2:29 | s |
@@ -107,6 +111,10 @@ edges
107111
| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal |
108112
| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal |
109113
| main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal |
114+
| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val |
115+
| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val |
116+
| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val |
117+
| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val |
110118
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
111119
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
112120
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s |
@@ -132,5 +140,6 @@ edges
132140
| main.js:47:65:47:73 | this.step | main.js:52:41:52:41 | s | main.js:47:65:47:73 | this.step | $@ based on $@ might later cause $@. | main.js:47:65:47:73 | this.step | HTML construction | main.js:52:41:52:41 | s | library input | main.js:47:54:47:85 | "<span> ... /span>" | cross-site scripting |
133141
| main.js:62:19:62:31 | settings.name | main.js:56:28:56:34 | options | main.js:62:19:62:31 | settings.name | $@ based on $@ might later cause $@. | main.js:62:19:62:31 | settings.name | HTML construction | main.js:56:28:56:34 | options | library input | main.js:62:11:62:40 | "<b>" + ... "</b>" | cross-site scripting |
134142
| main.js:67:63:67:69 | attrVal | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | $@ based on $@ might later cause $@. | main.js:67:63:67:69 | attrVal | HTML construction | main.js:66:35:66:41 | attrVal | library input | main.js:67:47:67:78 | "<img a ... "\\"/>" | cross-site scripting |
143+
| main.js:81:35:81:37 | val | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | $@ based on $@ might later cause $@. | main.js:81:35:81:37 | val | HTML construction | main.js:79:34:79:36 | val | library input | main.js:81:24:81:49 | "<span> ... /span>" | cross-site scripting |
135144
| typed.ts:2:29:2:29 | s | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | $@ based on $@ might later cause $@. | typed.ts:2:29:2:29 | s | HTML construction | typed.ts:1:39:1:39 | s | library input | typed.ts:3:31:3:34 | html | cross-site scripting |
136145
| typed.ts:8:40:8:40 | s | typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | $@ based on $@ might later cause $@. | typed.ts:8:40:8:40 | s | HTML construction | typed.ts:6:43:6:43 | s | library input | typed.ts:8:29:8:52 | "<span> ... /span>" | cross-site scripting |

javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,13 @@ module.exports.intentionalTemplate = function (obj) {
7575
const html = "<span>" + obj.spanTemplate + "</span>"; // OK
7676
document.querySelector("#template").innerHTML = html;
7777
}
78+
79+
module.exports.types = function (val) {
80+
if (typeof val === "string") {
81+
$("#foo").html("<span>" + val + "</span>"); // NOT OK
82+
} else if (typeof val === "number") {
83+
$("#foo").html("<span>" + val + "</span>"); // OK
84+
} else if (typeof val === "boolean") {
85+
$("#foo").html("<span>" + val + "</span>"); // OK
86+
}
87+
}

swift/ql/lib/codeql/swift/elements/Locatable.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
private import codeql.swift.generated.Locatable
2+
private import codeql.swift.elements.File
23

34
class Locatable extends LocatableBase {
45
pragma[nomagic]
@@ -7,4 +8,9 @@ class Locatable extends LocatableBase {
78
or
89
not exists(LocatableBase.super.getLocation()) and result instanceof UnknownLocation
910
}
11+
12+
/**
13+
* Gets the primary file where this element occurs.
14+
*/
15+
File getFile() { result = getLocation().getFile() }
1016
}

swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @kind problem
55
* @problem.severity error
66
* @security-severity 7.8
7-
* @precision TODO
7+
* @precision high
88
* @id swift/string-length-conflation
99
* @tags security
1010
* external/cwe/cwe-135

swift/ql/src/queries/placeholder.ql

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | getFunction: | dot_syntax_call.swift:6:3:6:3 | foo(_:_:) | getBaseExpr: | dot_syntax_call.swift:6:1:6:1 | X.Type |
2+
| dot_syntax_call.swift:7:1:7:3 | call to bar() | getFunction: | dot_syntax_call.swift:7:3:7:3 | bar() | getBaseExpr: | dot_syntax_call.swift:7:1:7:1 | X.Type |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// generated by codegen/codegen.py
2+
import codeql.swift.elements
3+
import TestUtils
4+
5+
from DotSyntaxCallExpr x, Expr getFunction, Expr getBaseExpr
6+
where
7+
toBeTested(x) and
8+
not x.isUnknown() and
9+
getFunction = x.getFunction() and
10+
getBaseExpr = x.getBaseExpr()
11+
select x, "getFunction:", getFunction, "getBaseExpr:", getBaseExpr

0 commit comments

Comments
 (0)