Skip to content

Commit 3636708

Browse files
author
Esben Sparre Andreasen
committed
JS: extract and expose StringConcatenationTaintStep in TaintTracking
1 parent 7607b6b commit 3636708

File tree

4 files changed

+26
-31
lines changed

4 files changed

+26
-31
lines changed

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,12 @@ module TaintTracking {
309309
}
310310

311311
/**
312-
* A taint propagating data flow edge arising from string append and other string
313-
* operations defined in the standard library.
312+
* A taint propagating data flow edge arising from string concatenations.
314313
*
315-
* Note that since we cannot easily distinguish string append from addition, we consider
316-
* any `+` operation to propagate taint.
314+
* Note that since we cannot easily distinguish string append from addition,
315+
* we consider any `+` operation to propagate taint.
317316
*/
318-
private class StringManipulationTaintStep extends AdditionalTaintStep, DataFlow::ValueNode {
317+
class StringConcatenationTaintStep extends AdditionalTaintStep, DataFlow::ValueNode {
319318
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
320319
succ = this and
321320
(
@@ -329,8 +328,19 @@ module TaintTracking {
329328
or
330329
// templating propagates taint
331330
astNode.(TemplateLiteral).getAnElement() = pred.asExpr()
332-
or
333-
// other string operations that propagate taint
331+
)
332+
}
333+
}
334+
335+
/**
336+
* A taint propagating data flow edge arising from string manipulation
337+
* functions defined in the standard library.
338+
*/
339+
private class StringManipulationTaintStep extends AdditionalTaintStep, DataFlow::ValueNode {
340+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
341+
succ = this and
342+
(
343+
// string operations that propagate taint
334344
exists (string name | name = astNode.(MethodCallExpr).getMethodName() |
335345
pred.asExpr() = astNode.(MethodCallExpr).getReceiver() and
336346
( // sorted, interesting, properties of String.prototype

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

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,30 +52,11 @@ module CleartextLogging {
5252
}
5353

5454
override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg) {
55-
// A taint propagating data flow edge arising from string operations
56-
exists (AST::ValueNode astNode |
57-
astNode = trg.(DataFlow::ValueNode).getAstNode() |
58-
// addition propagates
59-
astNode.(AddExpr).getAnOperand() = src.asExpr() or
60-
astNode.(AssignAddExpr).getAChildExpr() = src.asExpr() or
61-
exists (SsaExplicitDefinition ssa |
62-
astNode = ssa.getVariable().getAUse() and
63-
src.asExpr().(AssignAddExpr) = ssa.getDef()
64-
)
65-
or
66-
// templating propagates
67-
astNode.(TemplateLiteral).getAnElement() = src.asExpr()
68-
or
69-
// other string operations that propagate
70-
exists (string name | name = astNode.(MethodCallExpr).getMethodName() |
71-
src.asExpr() = astNode.(MethodCallExpr).getReceiver() and
72-
(
73-
// sorted, interesting, properties of Object.prototype
74-
name = "toString" or
75-
name = "valueOf"
76-
)
77-
)
78-
)
55+
any (TaintTracking::StringConcatenationTaintStep s).step(src, trg)
56+
or
57+
exists (string name | name = "toString" or name = "valueOf" |
58+
src.(DataFlow::SourceNode).getAMethodCall(name) = trg
59+
)
7960
or
8061
// A taint propagating data flow edge through objects: a tainted write taints the entire object.
8162
exists (DataFlow::PropWrite write |

javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
| passwords.js:78:17:78:38 | temp.en ... assword | Sensitive data returned by $@ is logged here. | passwords.js:77:37:77:53 | req.body.password | an access to password |
1313
| passwords.js:81:17:81:31 | `pw: ${secret}` | Sensitive data returned by $@ is logged here. | passwords.js:80:18:80:25 | password | an access to password |
1414
| passwords.js:114:25:114:50 | "Passwo ... assword | Sensitive data returned by $@ is logged here. | passwords.js:114:43:114:50 | password | an access to password |
15+
| passwords.js:122:17:122:49 | name + ... tring() | Sensitive data returned by $@ is logged here. | passwords.js:122:31:122:38 | password | an access to password |
16+
| passwords.js:123:17:123:48 | name + ... lueOf() | Sensitive data returned by $@ is logged here. | passwords.js:123:31:123:38 | password | an access to password |
1517
| passwords_in_server_1.js:6:13:6:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_1.js:6:13:6:20 | password | an access to password |
1618
| passwords_in_server_2.js:3:13:3:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_2.js:3:13:3:20 | password | an access to password |
1719
| passwords_in_server_3.js:2:13:2:20 | password | Sensitive data returned by $@ is logged here. | passwords_in_server_3.js:2:13:2:20 | password | an access to password |

javascript/ql/test/query-tests/Security/CWE-312/passwords.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,6 @@
119119
console.log("Password is: " + password); // OK
120120
}
121121

122+
console.log(name + ", " + password.toString()); // NOT OK
123+
console.log(name + ", " + password.valueOf()); // NOT OK
122124
});

0 commit comments

Comments
 (0)