mirror of
https://github.com/github/codeql.git
synced 2026-05-03 04:39:29 +02:00
add support for the prettier API
This commit is contained in:
@@ -104,6 +104,7 @@ import semmle.javascript.frameworks.Nest
|
||||
import semmle.javascript.frameworks.Next
|
||||
import semmle.javascript.frameworks.NoSQL
|
||||
import semmle.javascript.frameworks.PkgCloud
|
||||
import semmle.javascript.frameworks.Prettier
|
||||
import semmle.javascript.frameworks.PropertyProjection
|
||||
import semmle.javascript.frameworks.Puppeteer
|
||||
import semmle.javascript.frameworks.React
|
||||
|
||||
52
javascript/ql/src/semmle/javascript/frameworks/Prettier.qll
Normal file
52
javascript/ql/src/semmle/javascript/frameworks/Prettier.qll
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Provides classes and predicates for working with the [prettier](https://www.npmjs.com/package/prettier) library.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
||||
/** Provides classes and predicates modelling aspects of the [prettier](https://www.npmjs.com/package/prettier) library. */
|
||||
private module Prettier {
|
||||
/**
|
||||
* A taint step from the [prettier API](https://prettier.io/docs/en/api.html).
|
||||
*/
|
||||
private class PrettierTaintStep extends TaintTracking::SharedTaintStep {
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(API::CallNode call |
|
||||
call = API::moduleImport("prettier").getMember("format").getACall()
|
||||
|
|
||||
pred = call.getArgument(0) and
|
||||
succ = call
|
||||
)
|
||||
or
|
||||
exists(API::CallNode call |
|
||||
call = API::moduleImport("prettier").getMember("formatWithCursor").getACall()
|
||||
|
|
||||
pred = call.getArgument(0) and
|
||||
succ = call.getReturn().getMember("formatted").getAnImmediateUse()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private import semmle.javascript.security.dataflow.TaintedPathCustomizations::TaintedPath as TaintedPath
|
||||
|
||||
/**
|
||||
* An argument given to the `prettier` library specificing the location of a config file.
|
||||
*/
|
||||
private class PrettierFileSink extends TaintedPath::Sink {
|
||||
PrettierFileSink() {
|
||||
this =
|
||||
API::moduleImport("prettier")
|
||||
.getMember(["resolveConfig", "resolveConfigFile", "getFileInfo"])
|
||||
.getACall()
|
||||
.getArgument(0)
|
||||
or
|
||||
this =
|
||||
API::moduleImport("prettier")
|
||||
.getMember("resolveConfig")
|
||||
.getACall()
|
||||
.getParameter(1)
|
||||
.getMember("config")
|
||||
.getARhs()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2271,6 +2271,25 @@ nodes
|
||||
| other-fs-libraries.js:52:24:52:27 | path |
|
||||
| other-fs-libraries.js:52:24:52:27 | path |
|
||||
| other-fs-libraries.js:52:24:52:27 | path |
|
||||
| prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p |
|
||||
| prettier.js:6:13:6:13 | p |
|
||||
| prettier.js:6:13:6:13 | p |
|
||||
| prettier.js:6:13:6:13 | p |
|
||||
| prettier.js:6:13:6:13 | p |
|
||||
| prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:11:44:11:44 | p |
|
||||
| pupeteer.js:5:9:5:71 | tainted |
|
||||
| pupeteer.js:5:9:5:71 | tainted |
|
||||
| pupeteer.js:5:9:5:71 | tainted |
|
||||
@@ -6668,6 +6687,30 @@ edges
|
||||
| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) |
|
||||
| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) |
|
||||
| other-fs-libraries.js:49:24:49:30 | req.url | other-fs-libraries.js:49:14:49:37 | url.par ... , true) |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:7:28:7:28 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:11:6:28 | p | prettier.js:11:44:11:44 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| prettier.js:6:13:6:13 | p | prettier.js:6:11:6:28 | p |
|
||||
| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted |
|
||||
| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted |
|
||||
| pupeteer.js:5:9:5:71 | tainted | pupeteer.js:9:28:9:34 | tainted |
|
||||
@@ -8295,6 +8338,8 @@ edges
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
const express = require('express');
|
||||
const prettier = require("prettier");
|
||||
|
||||
const app = express();
|
||||
app.get('/some/path', function (req, res) {
|
||||
const { p } = req.params;
|
||||
prettier.resolveConfig(p).then((options) => { // NOT OK
|
||||
const formatted = prettier.format("foo", options);
|
||||
});
|
||||
|
||||
prettier.resolveConfig("foo", {config: p}).then((options) => { // NOT OK
|
||||
const formatted = prettier.format("bar", options);
|
||||
});
|
||||
});
|
||||
@@ -187,6 +187,12 @@ nodes
|
||||
| tst3.js:5:9:5:9 | p |
|
||||
| tst3.js:6:12:6:12 | p |
|
||||
| tst3.js:6:12:6:12 | p |
|
||||
| tst3.js:11:9:11:74 | code |
|
||||
| tst3.js:11:16:11:74 | prettie ... bel" }) |
|
||||
| tst3.js:11:32:11:39 | reg.body |
|
||||
| tst3.js:11:32:11:39 | reg.body |
|
||||
| tst3.js:12:12:12:15 | code |
|
||||
| tst3.js:12:12:12:15 | code |
|
||||
edges
|
||||
| ReflectedXss.js:8:33:8:45 | req.params.id | 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 |
|
||||
@@ -342,6 +348,11 @@ edges
|
||||
| tst3.js:5:7:5:24 | p | tst3.js:6:12:6:12 | p |
|
||||
| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p |
|
||||
| tst3.js:5:9:5:9 | p | tst3.js:5:7:5:24 | p |
|
||||
| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code |
|
||||
| tst3.js:11:9:11:74 | code | tst3.js:12:12:12:15 | code |
|
||||
| tst3.js:11:16:11:74 | prettie ... bel" }) | tst3.js:11:9:11:74 | code |
|
||||
| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) |
|
||||
| tst3.js:11:32:11:39 | reg.body | tst3.js:11:16:11:74 | prettie ... bel" }) |
|
||||
#select
|
||||
| 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 |
|
||||
| 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 |
|
||||
@@ -386,3 +397,4 @@ edges
|
||||
| tst2.js:36:12:36:12 | p | tst2.js:30:9:30:9 | p | tst2.js:36:12:36:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
@@ -40,3 +40,4 @@
|
||||
| tst2.js:36:12:36:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
|
||||
| tst2.js:37:12:37:18 | other.p | Cross-site scripting vulnerability due to $@. | tst2.js:30:9:30:9 | p | user-provided value |
|
||||
| tst3.js:6:12:6:12 | p | Cross-site scripting vulnerability due to $@. | tst3.js:5:9:5:9 | p | user-provided value |
|
||||
| tst3.js:12:12:12:15 | code | Cross-site scripting vulnerability due to $@. | tst3.js:11:32:11:39 | reg.body | user-provided value |
|
||||
|
||||
@@ -5,3 +5,9 @@ app.enable('x-powered-by').disable('x-powered-by').get('/', function (req, res)
|
||||
let { p } = req.params;
|
||||
res.send(p); // NOT OK
|
||||
});
|
||||
|
||||
const prettier = require("prettier");
|
||||
app.post("foobar", function (reg, res) {
|
||||
const code = prettier.format(reg.body, { semi: false, parser: "babel" });
|
||||
res.send(code); // NOT OK
|
||||
});
|
||||
Reference in New Issue
Block a user