diff --git a/create-a-container/app.js b/create-a-container/app.js index e94018cc..77811ee9 100644 --- a/create-a-container/app.js +++ b/create-a-container/app.js @@ -15,7 +15,6 @@ const morgan = require('morgan'); const fs = require('fs'); const SequelizeStore = require('express-session-sequelize')(session.Store); const path = require('path'); -const RateLimit = require('express-rate-limit'); const swaggerUi = require('swagger-ui-express'); const YAML = require('yamljs'); const { sequelize } = require('./models'); @@ -23,8 +22,6 @@ const { sequelize } = require('./models'); /** * @param {object} options * @param {string|string[]} options.sessionSecrets - express-session secret(s); required. - * @param {boolean} [options.rateLimit=true] - disable in tests: assertions on 4xx - * responses must not burn the budget. * @param {boolean} [options.accessLog=true] - morgan; disable in tests for quiet output. * @param {string} [options.mcpServerUrl] - origin of the MCP server to reverse-proxy * at /mcp (default: $MCP_SERVER_URL). Unset @@ -32,7 +29,6 @@ const { sequelize } = require('./models'); */ function buildApp({ sessionSecrets, - rateLimit = true, accessLog = true, mcpServerUrl = process.env.MCP_SERVER_URL, } = {}) { @@ -98,20 +94,6 @@ function buildApp({ app.use(express.static('public')); - // We rate limit unsuccessful (4xx/5xx statuses, excluding 404) to only 10 per 5 minutes, this - // should allow legitimate users a few tries to login or experiment without - // allowing bad-actors to abuse requests. 404s are excluded because browsers - // (especially Safari) automatically request favicon/apple-touch-icon paths that - // don't exist, and those harmless misses should not burn the rate-limit budget. - if (rateLimit) { - app.use(RateLimit({ - windowMs: 5 * 60 * 1000, - max: 10, - skipSuccessfulRequests: true, - requestWasSuccessful: (req, res) => res.statusCode < 400 || res.statusCode === 404, - })); - } - // CSRF guard for every handler that can see the session cookie (CodeQL // js/missing-token-validation). Behavior-preserving: csrfGuard skips // GET/HEAD/OPTIONS and Bearer-only requests, and every state-changing diff --git a/create-a-container/middlewares/__tests__/mcp-proxy.test.js b/create-a-container/middlewares/__tests__/mcp-proxy.test.js index 177d99d6..00236d8d 100644 --- a/create-a-container/middlewares/__tests__/mcp-proxy.test.js +++ b/create-a-container/middlewares/__tests__/mcp-proxy.test.js @@ -47,7 +47,6 @@ function startUpstream() { function build(mcpServerUrl) { return buildApp({ sessionSecrets: ['test-secret'], - rateLimit: false, accessLog: false, mcpServerUrl, }); diff --git a/create-a-container/package-lock.json b/create-a-container/package-lock.json index 880f51ba..97fe17e6 100644 --- a/create-a-container/package-lock.json +++ b/create-a-container/package-lock.json @@ -12,7 +12,6 @@ "csrf-sync": "^4.2.1", "dotenv": "^17.2.3", "express": "^5.2.1", - "express-rate-limit": "^8.5.1", "express-session": "^1.19.0", "express-session-sequelize": "^2.3.0", "morgan": "^1.11.0", @@ -2961,24 +2960,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/express-rate-limit": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", - "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", - "license": "MIT", - "dependencies": { - "ip-address": "^10.2.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" - } - }, "node_modules/express-session": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.19.0.tgz", @@ -3617,15 +3598,6 @@ "dev": true, "license": "ISC" }, - "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", diff --git a/create-a-container/package.json b/create-a-container/package.json index ee3a338c..6a856a5e 100644 --- a/create-a-container/package.json +++ b/create-a-container/package.json @@ -26,7 +26,6 @@ "csrf-sync": "^4.2.1", "dotenv": "^17.2.3", "express": "^5.2.1", - "express-rate-limit": "^8.5.1", "express-session": "^1.19.0", "express-session-sequelize": "^2.3.0", "morgan": "^1.11.0", diff --git a/create-a-container/tests/helpers/app.js b/create-a-container/tests/helpers/app.js index cfe20ebb..100182c6 100644 --- a/create-a-container/tests/helpers/app.js +++ b/create-a-container/tests/helpers/app.js @@ -4,8 +4,6 @@ * options: * * - fixed session secret (production reads secrets from the DB in server.js) - * - rate limiting off (tests assert on 4xx responses; the limiter would - * start rejecting them after 10) * - access log off (quiet output) * * Tests normally authenticate with a Bearer API key (apiAuth accepts it and @@ -23,7 +21,6 @@ const { buildApp: buildRealApp } = require('../../app'); function buildApp() { return buildRealApp({ sessionSecrets: ['test-secret'], - rateLimit: false, accessLog: false, }); }