Skip to content

Commit 169e67c

Browse files
authored
Merge pull request github#5990 from erik-krogh/prettier
Approved by asgerf
2 parents 8fb1566 + 4b98af0 commit 169e67c

File tree

9 files changed

+133
-0
lines changed

9 files changed

+133
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
lgtm,codescanning
2+
* The dataflow libraries now model dataflow in the prettier library.
3+
Affected packages are
4+
[prettier](https://npmjs.com/package/prettier)

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ import semmle.javascript.frameworks.Nest
104104
import semmle.javascript.frameworks.Next
105105
import semmle.javascript.frameworks.NoSQL
106106
import semmle.javascript.frameworks.PkgCloud
107+
import semmle.javascript.frameworks.Prettier
107108
import semmle.javascript.frameworks.PropertyProjection
108109
import semmle.javascript.frameworks.Puppeteer
109110
import semmle.javascript.frameworks.React
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Provides classes and predicates for working with the [prettier](https://www.npmjs.com/package/prettier) library.
3+
*/
4+
5+
import javascript
6+
7+
/** Provides classes and predicates modelling aspects of the [prettier](https://www.npmjs.com/package/prettier) library. */
8+
private module Prettier {
9+
/**
10+
* A taint step from the [prettier API](https://prettier.io/docs/en/api.html).
11+
*/
12+
private class PrettierTaintStep extends TaintTracking::SharedTaintStep {
13+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
14+
exists(API::CallNode call |
15+
call = API::moduleImport("prettier").getMember("format").getACall()
16+
|
17+
pred = call.getArgument(0) and
18+
succ = call
19+
)
20+
or
21+
exists(API::CallNode call |
22+
call = API::moduleImport("prettier").getMember("formatWithCursor").getACall()
23+
|
24+
pred = call.getArgument(0) and
25+
succ = call.getReturn().getMember("formatted").getAnImmediateUse()
26+
)
27+
}
28+
}
29+
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,27 @@ module TaintedPath {
661661
}
662662
}
663663

664+
/**
665+
* An argument given to the `prettier` library specifying the location of a config file.
666+
*/
667+
private class PrettierFileSink extends TaintedPath::Sink {
668+
PrettierFileSink() {
669+
this =
670+
API::moduleImport("prettier")
671+
.getMember(["resolveConfig", "resolveConfigFile", "getFileInfo"])
672+
.getACall()
673+
.getArgument(0)
674+
or
675+
this =
676+
API::moduleImport("prettier")
677+
.getMember("resolveConfig")
678+
.getACall()
679+
.getParameter(1)
680+
.getMember("config")
681+
.getARhs()
682+
}
683+
}
684+
664685
/**
665686
* Holds if there is a step `src -> dst` mapping `srclabel` to `dstlabel` relevant for path traversal vulnerabilities.
666687
*/

javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,6 +2271,25 @@ nodes
22712271
| other-fs-libraries.js:52:24:52:27 | path |
22722272
| other-fs-libraries.js:52:24:52:27 | path |
22732273
| other-fs-libraries.js:52:24:52:27 | path |
2274+
| prettier.js:6:11:6:28 | p |
2275+
| prettier.js:6:11:6:28 | p |
2276+
| prettier.js:6:11:6:28 | p |
2277+
| prettier.js:6:11:6:28 | p |
2278+
| prettier.js:6:13:6:13 | p |
2279+
| prettier.js:6:13:6:13 | p |
2280+
| prettier.js:6:13:6:13 | p |
2281+
| prettier.js:6:13:6:13 | p |
2282+
| prettier.js:6:13:6:13 | p |
2283+
| prettier.js:7:28:7:28 | p |
2284+
| prettier.js:7:28:7:28 | p |
2285+
| prettier.js:7:28:7:28 | p |
2286+
| prettier.js:7:28:7:28 | p |
2287+
| prettier.js:7:28:7:28 | p |
2288+
| prettier.js:11:44:11:44 | p |
2289+
| prettier.js:11:44:11:44 | p |
2290+
| prettier.js:11:44:11:44 | p |
2291+
| prettier.js:11:44:11:44 | p |
2292+
| prettier.js:11:44:11:44 | p |
22742293
| pupeteer.js:5:9:5:71 | tainted |
22752294
| pupeteer.js:5:9:5:71 | tainted |
22762295
| pupeteer.js:5:9:5:71 | tainted |
@@ -6680,6 +6699,30 @@ edges
66806699
| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) |
66816700
| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) |
66826701
| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) |
6702+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6703+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6704+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6705+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6706+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6707+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6708+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6709+
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
6710+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6711+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6712+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6713+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6714+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6715+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6716+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6717+
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
6718+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
6719+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
6720+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
6721+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
6722+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
6723+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
6724+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
6725+
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
66836726
| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted |
66846727
| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted |
66856728
| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted |
@@ -8309,6 +8352,8 @@ edges
83098352
| other-fs-libraries.js:42:53:42:56 | path | other-fs-libraries.js:38:24:38:30 | req.url | other-fs-libraries.js:42:53:42:56 | path | This path depends on $@. | other-fs-libraries.js:38:24:38:30 | req.url | a user-provided value |
83108353
| other-fs-libraries.js:51:19:51:22 | path | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:51:19:51:22 | path | This path depends on $@. | other-fs-libraries.js:49:24:49:30 | req.url | a user-provided value |
83118354
| other-fs-libraries.js:52:24:52:27 | path | other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:52:24:52:27 | path | This path depends on $@. | other-fs-libraries.js:49:24:49:30 | req.url | a user-provided value |
8355+
| prettier.js:7:28:7:28 | p | prettier.js:6:13:6:13 | p | prettier.js:7:28:7:28 | p | This path depends on $@. | prettier.js:6:13:6:13 | p | a user-provided value |
8356+
| prettier.js:11:44:11:44 | p | prettier.js:6:13:6:13 | p | prettier.js:11:44:11:44 | p | This path depends on $@. | prettier.js:6:13:6:13 | p | a user-provided value |
83128357
| pupeteer.js:9:28:9:34 | tainted | pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:9:28:9:34 | tainted | This path depends on $@. | pupeteer.js:5:28:5:53 | parseTo ... t).name | a user-provided value |
83138358
| pupeteer.js:13:37:13:43 | tainted | pupeteer.js:5:28:5:53 | parseTo ... t).name | pupeteer.js:13:37:13:43 | tainted | This path depends on $@. | pupeteer.js:5:28:5:53 | parseTo ... t).name | a user-provided value |
83148359
| tainted-access-paths.js:8:19:8:22 | path | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:8:19:8:22 | path | This path depends on $@. | tainted-access-paths.js:6:24:6:30 | req.url | a user-provided value |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const express = require('express');
2+
const prettier = require("prettier");
3+
4+
const app = express();
5+
app.get('/some/path', function (req, res) {
6+
const { p } = req.params;
7+
prettier.resolveConfig(p).then((options) => { // NOT OK
8+
const formatted = prettier.format("foo", options);
9+
});
10+
11+
prettier.resolveConfig("foo", {config: p}).then((options) => { // NOT OK
12+
const formatted = prettier.format("bar", options);
13+
});
14+
});

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ nodes
195195
| tst3.js:5:9:5:9 | p |
196196
| tst3.js:6:12:6:12 | p |
197197
| tst3.js:6:12:6:12 | p |
198+
| tst3.js:11:9:11:74 | code |
199+
| tst3.js:11:16:11:74 | prettie ... bel" }) |
200+
| tst3.js:11:32:11:39 | reg.body |
201+
| tst3.js:11:32:11:39 | reg.body |
202+
| tst3.js:12:12:12:15 | code |
203+
| tst3.js:12:12:12:15 | code |
198204
edges
199205
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
200206
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
@@ -357,6 +363,11 @@ edges
357363
| tst3.js:5:7:5:24 | p | tst3.js:6:12:6:12 | p |
358364
| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p |
359365
| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p |
366+
| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code |
367+
| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code |
368+
| tst3.js:11:16:11:74 | prettie ... bel" }) | tst3.js:11:9:11:74 | code |
369+
| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) |
370+
| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) |
360371
#select
361372
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
362373
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value |
@@ -402,3 +413,4 @@ edges
402413
| tst2.js:37:12:37:18 | other.p | tst2.js:30:9:30:9 | p | tst2.js:37:12:37:18 | other.p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
403414
| tst2.js:51:12:51:17 | unsafe | tst2.js:43:9:43:9 | p | tst2.js:51:12:51:17 | unsafe | Cross-site scripting vulnerability due to $@. | tst2.js:43:9:43:9 | p | user-provided value |
404415
| tst3.js:6:12:6:12 | p | tst3.js:5:9:5:9 | p | tst3.js:6:12:6:12 | p | Cross-site scripting vulnerability due to $@. | tst3.js:5:9:5:9 | p | user-provided value |
416+
| tst3.js:12:12:12:15 | code | tst3.js:11:32:11:39 | reg.body | tst3.js:12:12:12:15 | code | Cross-site scripting vulnerability due to $@. | tst3.js:11:32:11:39 | reg.body | user-provided value |

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@
4141
| tst2.js:37:12:37:18 | other.p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
4242
| tst2.js:51:12:51:17 | unsafe | Cross-site scripting vulnerability due to $@. | tst2.js:43:9:43:9 | p | user-provided value |
4343
| tst3.js:6:12:6:12 | p | Cross-site scripting vulnerability due to $@. | tst3.js:5:9:5:9 | p | user-provided value |
44+
| tst3.js:12:12:12:15 | code | Cross-site scripting vulnerability due to $@. | tst3.js:11:32:11:39 | reg.body | user-provided value |

javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/tst3.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ app.enable('x-powered-by').disable('x-powered-by').get('/', function (req, res)
55
let { p } = req.params;
66
res.send(p); // NOT OK
77
});
8+
9+
const prettier = require("prettier");
10+
app.post("foobar", function (reg, res) {
11+
const code = prettier.format(reg.body, { semi: false, parser: "babel" });
12+
res.send(code); // NOT OK
13+
});

0 commit comments

Comments
 (0)