Merge branch 'main' into js/vercel-node-framework

This commit is contained in:
murderteeth
2026-04-25 14:19:43 -04:00
committed by GitHub
597 changed files with 142900 additions and 101799 deletions

View File

@@ -1,3 +1,11 @@
## 2.6.28
No user-facing changes.
## 2.6.27
No user-facing changes.
## 2.6.26
No user-facing changes.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for JavaScript](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-javascript/).

View File

@@ -0,0 +1,3 @@
## 2.6.27
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 2.6.28
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 2.6.26
lastReleaseVersion: 2.6.28

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 2.6.27-dev
version: 2.6.29-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -10,6 +10,10 @@
* `type, path, kind`
* - Summaries:
* `type, path, input, output, kind`
* - Barriers:
* `type, path, kind`
* - BarrierGuards:
* `type, path, acceptingValue, kind`
* - Types:
* `type1, type2, path`
*
@@ -42,7 +46,8 @@
* 3. The `input` and `output` columns specify how data enters and leaves the element selected by the
* first `(type, path)` tuple. Both strings are `.`-separated access paths
* of the same syntax as the `path` column.
* 4. The `kind` column is a tag that can be referenced from QL to determine to
* 4. The `acceptingValue` column of barrier guard models specifies which branch of the guard is blocking flow. It can be "true" or "false".
* 5. The `kind` column is a tag that can be referenced from QL to determine to
* which classes the interpreted elements should be added. For example, for
* sources `"remote"` indicates a default remote flow source, and for summaries
* `"taint"` indicates a default additional taint step and `"value"` indicates a
@@ -355,11 +360,11 @@ private predicate barrierModel(string type, string path, string kind, string mod
/** Holds if a barrier guard model exists for the given parameters. */
private predicate barrierGuardModel(
string type, string path, string branch, string kind, string model
string type, string path, string acceptingValue, string kind, string model
) {
// No deprecation adapter for barrier models, they were not around back then.
exists(QlBuiltins::ExtensionId madId |
Extensions::barrierGuardModel(type, path, branch, kind, madId) and
Extensions::barrierGuardModel(type, path, acceptingValue, kind, madId) and
model = "MaD:" + madId.toString()
)
}
@@ -783,16 +788,16 @@ module ModelOutput {
}
/**
* Holds if a barrier model contributed `barrier` with the given `kind` for the given `branch`.
* Holds if a barrier model contributed `barrier` with the given `kind` for the given `acceptingValue`.
*/
cached
API::Node getABarrierGuardNode(string kind, boolean branch, string model) {
exists(string type, string path, string branch_str |
branch = true and branch_str = "true"
API::Node getABarrierGuardNode(string kind, boolean acceptingValue, string model) {
exists(string type, string path, string acceptingValue_str |
acceptingValue = true and acceptingValue_str = "true"
or
branch = false and branch_str = "false"
acceptingValue = false and acceptingValue_str = "false"
|
barrierGuardModel(type, path, branch_str, kind, model) and
barrierGuardModel(type, path, acceptingValue_str, kind, model) and
result = getNodeFromPath(type, path)
)
}
@@ -856,12 +861,12 @@ module ModelOutput {
API::Node getABarrierNode(string kind) { result = getABarrierNode(kind, _) }
/**
* Holds if an external model contributed `barrier-guard` with the given `kind` and `branch`.
* Holds if an external model contributed `barrier-guard` with the given `kind` and `acceptingValue`.
*
* INTERNAL: Do not use.
*/
API::Node getABarrierGuardNode(string kind, boolean branch) {
result = getABarrierGuardNode(kind, branch, _)
API::Node getABarrierGuardNode(string kind, boolean acceptingValue) {
result = getABarrierGuardNode(kind, acceptingValue, _)
}
/**

View File

@@ -33,11 +33,11 @@ extensible predicate barrierModel(
* of the given `kind` and `madId` is the data extension row number.
* `path` is assumed to lead to a parameter of a call (possibly `self`), and
* the call is guarding the parameter.
* `branch` is either `true` or `false`, indicating which branch of the guard
* is protecting the parameter.
* `acceptingValue` is either `true` or `false`, indicating which branch of
* the guard is protecting the parameter.
*/
extensible predicate barrierGuardModel(
string type, string path, string branch, string kind, QlBuiltins::ExtensionId madId
string type, string path, string acceptingValue, string kind, QlBuiltins::ExtensionId madId
);
/**

View File

@@ -191,3 +191,21 @@ class RouteHandlerLimitedByRateLimiterFlexible extends RateLimitingMiddleware in
private class FastifyRateLimiter extends RateLimitingMiddleware {
FastifyRateLimiter() { this = DataFlow::moduleImport("fastify-rate-limit") }
}
/**
* An options object with a `rateLimit` config passed to a Fastify shorthand route method,
* such as `fastify.post('/path', { config: { rateLimit: { ... } } }, handler)`.
*/
private class FastifyPerRouteRateLimit extends RateLimitingMiddleware {
FastifyPerRouteRateLimit() {
exists(Fastify::RouteSetup setup |
not setup.getMethodName() = ["route", "addHook"] and
setup.getNumArgument() >= 3 and
this.flowsTo(setup.getArgument(1))
|
exists(this.getAPropertySource("config").getAPropertySource("rateLimit"))
or
exists(this.getAPropertySource("rateLimit"))
)
}
}

View File

@@ -1,3 +1,14 @@
## 2.3.8
### Minor Analysis Improvements
* The query `js/missing-rate-limiting` now takes Fastify per-route
rate limiting into account.
## 2.3.7
No user-facing changes.
## 2.3.6
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 2.3.7
No user-facing changes.

View File

@@ -0,0 +1,6 @@
## 2.3.8
### Minor Analysis Improvements
* The query `js/missing-rate-limiting` now takes Fastify per-route
rate limiting into account.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 2.3.6
lastReleaseVersion: 2.3.8

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 2.3.7-dev
version: 2.3.9-dev
groups:
- javascript
- queries

View File

@@ -9,3 +9,4 @@
| tst.js:64:25:64:63 | functio ... req); } | This route handler performs $@, but is not rate-limited. | tst.js:64:46:64:60 | verifyUser(req) | authorization |
| tst.js:76:25:76:53 | catchAs ... ndler1) | This route handler performs $@, but is not rate-limited. | tst.js:14:40:14:46 | login() | authorization |
| tst.js:88:24:88:40 | expensiveHandler1 | This route handler performs $@, but is not rate-limited. | tst.js:14:40:14:46 | login() | authorization |
| tst.js:112:28:112:44 | expensiveHandler1 | This route handler performs $@, but is not rate-limited. | tst.js:14:40:14:46 | login() | authorization |

View File

@@ -88,3 +88,25 @@ const fastifyApp = require('fastify')();
fastifyApp.get('/foo', expensiveHandler1); // $ Alert
fastifyApp.register(require('fastify-rate-limit'));
fastifyApp.get('/bar', expensiveHandler1);
// Fastify per-route rate limiting via config.rateLimit
const fastifyApp2 = require('fastify')();
fastifyApp2.register(require('@fastify/rate-limit'));
fastifyApp2.post('/login', {
config: {
rateLimit: {
max: 3,
timeWindow: '1 minute'
}
}
}, expensiveHandler1); // OK - has per-route rateLimit config
fastifyApp2.post('/signup', {
rateLimit: {
max: 5,
timeWindow: '1 minute'
}
}, expensiveHandler1); // OK - has per-route rateLimit directly in options
fastifyApp2.post('/other', expensiveHandler1); // $ Alert - no rate limiting