Skip to content

Commit 0647743

Browse files
authored
Merge pull request #467 from xiemaisi/js/amd-imports
Approved by asger-semmle
2 parents 57bbe02 + 19b9b85 commit 0647743

File tree

6 files changed

+53
-0
lines changed

6 files changed

+53
-0
lines changed

change-notes/1.19/analysis-javascript.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
* The taint tracking library now recognizes additional sanitization patterns. This may give fewer false-positive results for the security queries.
88

9+
* Support for AMD modules has been improved. This may give additional results for the security queries as well as any queries that use type inference on code bases that use such modules.
10+
911
* Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following features:
1012
- file system access, for example through [fs-extra](https://github.com/jprichardson/node-fs-extra) or [globby](https://www.npmjs.com/package/globby)
1113
- outbound network access, for example through the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)

javascript/ql/src/semmle/javascript/dataflow/internal/InterModuleTypeInference.qll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,42 @@ private class AnalyzedAmdExport extends AnalyzedPropertyWrite, DataFlow::ValueNo
232232
}
233233
}
234234

235+
/**
236+
* Flow analysis for AMD imports, interpreted as an implicit read of
237+
* the `module.exports` property of the imported module.
238+
*/
239+
private class AnalyzedAmdImport extends AnalyzedPropertyRead, DataFlow::Node {
240+
Module required;
241+
242+
AnalyzedAmdImport() {
243+
exists (AMDModule amd, PathExpr dep, Parameter p |
244+
amd.getDefine().dependencyParameter(dep, p) and
245+
this = DataFlow::parameterNode(p) and
246+
required.getFile() = amd.resolve(dep)
247+
)
248+
}
249+
250+
override predicate reads(AbstractValue base, string propName) {
251+
base = TAbstractModuleObject(required) and
252+
propName = "exports"
253+
}
254+
}
255+
256+
/**
257+
* Flow analysis for parameters corresponding to AMD imports.
258+
*/
259+
private class AnalyzedAmdParameter extends AnalyzedVarDef, @vardecl {
260+
AnalyzedAmdImport imp;
261+
262+
AnalyzedAmdParameter() {
263+
imp = DataFlow::parameterNode(this)
264+
}
265+
266+
override AbstractValue getAnRhsValue() {
267+
result = imp.getALocalValue()
268+
}
269+
}
270+
235271
/**
236272
* Flow analysis for exports that export a single value.
237273
*/

javascript/ql/test/library-tests/Flow/AbstractValues.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
| amd2.js:1:8:3:1 | anonymous function |
1616
| amd2.js:1:8:3:1 | instance of anonymous function |
1717
| amd2.js:2:10:2:22 | object literal |
18+
| amd3.js:1:1:5:0 | exports object of module amd3 |
19+
| amd3.js:1:1:5:0 | module object of module amd3 |
20+
| amd3.js:1:24:4:1 | anonymous function |
21+
| amd3.js:1:24:4:1 | instance of anonymous function |
1822
| amd.js:1:1:7:0 | exports object of module amd |
1923
| amd.js:1:1:7:0 | module object of module amd |
2024
| amd.js:1:31:6:1 | anonymous function |

javascript/ql/test/library-tests/Flow/abseval.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
| a.js:9:5:9:5 | z | a.js:9:9:9:18 | someGlobal | file://:0:0:0:0 | non-zero value |
88
| a.js:9:5:9:5 | z | a.js:9:9:9:18 | someGlobal | file://:0:0:0:0 | true |
99
| a.js:14:12:14:24 | notAlwaysZero | a.js:14:28:14:28 | 0 | file://:0:0:0:0 | 0 |
10+
| amd3.js:2:7:2:8 | _a | amd3.js:2:12:2:12 | a | a.js:1:1:18:0 | exports object of module a |
11+
| amd3.js:2:7:2:8 | _a | amd3.js:2:12:2:12 | a | file://:0:0:0:0 | indefinite value (call) |
12+
| amd3.js:3:7:3:8 | _c | amd3.js:3:12:3:12 | c | c.js:1:1:7:0 | exports object of module c |
13+
| amd3.js:3:7:3:8 | _c | amd3.js:3:12:3:12 | c | c.js:1:18:1:19 | object literal |
14+
| amd3.js:3:7:3:8 | _c | amd3.js:3:12:3:12 | c | file://:0:0:0:0 | indefinite value (call) |
1015
| amd.js:2:7:2:7 | m | amd.js:2:11:2:13 | mod | amd.js:1:1:7:0 | module object of module amd |
1116
| amd.js:2:7:2:7 | m | amd.js:2:11:2:13 | mod | file://:0:0:0:0 | indefinite value (call) |
1217
| amd.js:3:7:3:7 | e | amd.js:3:11:3:13 | exp | amd.js:1:1:7:0 | exports object of module amd |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
define(['./a', './c'], function(a, c) {
2+
var _a = a;
3+
var _c = c;
4+
});

javascript/ql/test/library-tests/Flow/types.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
| a.js:1:19:1:19 | y | a.js:1:23:1:23 | 0 | number |
44
| a.js:9:5:9:5 | z | a.js:9:9:9:18 | someGlobal | boolean, class, date, function, null, number, object, regular expression,string or undefined |
55
| a.js:14:12:14:24 | notAlwaysZero | a.js:14:28:14:28 | 0 | number |
6+
| amd3.js:2:7:2:8 | _a | amd3.js:2:12:2:12 | a | boolean, class, date, function, null, number, object, regular expression,string or undefined |
7+
| amd3.js:3:7:3:8 | _c | amd3.js:3:12:3:12 | c | boolean, class, date, function, null, number, object, regular expression,string or undefined |
68
| amd.js:2:7:2:7 | m | amd.js:2:11:2:13 | mod | boolean, class, date, function, null, number, object, regular expression,string or undefined |
79
| amd.js:3:7:3:7 | e | amd.js:3:11:3:13 | exp | boolean, class, date, function, null, number, object, regular expression,string or undefined |
810
| arguments.js:2:7:2:7 | y | arguments.js:2:11:2:11 | x | number |

0 commit comments

Comments
 (0)