Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/codeql-admin-rate-limit-models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nostream": patch
---

fix: teach CodeQL to recognize custom admin rate limit middleware
8 changes: 8 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: nostream-codeql

packs:
javascript-typescript:
- cameri/nostream-javascript-models

queries:
- uses: security-and-quality
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Models Nostream's custom Redis-backed rate limit middleware for CodeQL's
* js/missing-rate-limiting query.
*
* CodeQL only recognizes popular npm rate limiters by default. Nostream uses
* in-repo middleware that calls isAdminRateLimited() / isRateLimited().
*/

import javascript
import semmle.javascript.security.dataflow.MissingRateLimiting

private predicate isNostreamRateLimitCheck(CallExpr call, string calleeName) {
call.getCalleeName() = calleeName
}

private predicate isInFile(Function fn, string fileSuffix) {
fn.getFile().getRelativePath().regexpMatch(".*/" + fileSuffix + "$")
}

/**
* An admin route middleware function that invokes isAdminRateLimited().
*/
class NostreamAdminRateLimiterFunction extends DataFlow::FunctionNode {
NostreamAdminRateLimiterFunction() {
exists(CallExpr call |
isNostreamRateLimitCheck(call, "isAdminRateLimited") and
call.getEnclosingFunction() = this.getFunction() and
isInFile(this.getFunction(), "admin-rate-limit-middleware.ts")
)
}
}

/**
* A connection-level middleware function that invokes isRateLimited().
*/
class NostreamConnectionRateLimiterFunction extends DataFlow::FunctionNode {
NostreamConnectionRateLimiterFunction() {
exists(CallExpr call |
isNostreamRateLimitCheck(call, "isRateLimited") and
call.getEnclosingFunction() = this.getFunction() and
isInFile(this.getFunction(), "rate-limiter-middleware.ts")
)
}
}

class NostreamAdminRateLimitMiddleware extends RateLimitingMiddleware instanceof NostreamAdminRateLimiterFunction {
}

class NostreamConnectionRateLimitMiddleware extends RateLimitingMiddleware instanceof NostreamConnectionRateLimiterFunction {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: cameri/nostream-javascript-models
version: 0.0.1
library: true
dependencies:
codeql/javascript-all: "*"
12 changes: 1 addition & 11 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,7 @@ jobs:
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in
# a config file. By default, queries listed here will override any
# specified in a config file.
# Prefix the list here with "+" to use these queries and those in
# the config file.

# For more details on CodeQL's query packs, refer to:
# https://docs.github.com/en/code-security/code-scanning/
# automatically-scanning-your-code-for-vulnerabilities-and-errors/
# configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
config-file: ./.github/codeql/codeql-config.yml

# If the analyze step fails for one of the languages you are analyzing
# with "We were unable to automatically build your code", modify the
Expand Down
Loading