diff --git a/backend/package.json b/backend/package.json index 940af3ecb..9f5e7e644 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,6 +29,7 @@ "dotenv": "^10.0.0", "email-templates": "^10.0.1", "express": "^4.17.1", + "express-slow-down": "^2.0.1", "gradido-database": "file:../database", "graphql": "^15.5.1", "graphql-request": "5.0.0", diff --git a/backend/src/server/createServer.ts b/backend/src/server/createServer.ts index e10b6cb5c..250a4b901 100644 --- a/backend/src/server/createServer.ts +++ b/backend/src/server/createServer.ts @@ -4,6 +4,7 @@ import { Connection as DbConnection } from '@dbTools/typeorm' import { ApolloServer } from 'apollo-server-express' import express, { Express, json, urlencoded } from 'express' +import { slowDown } from 'express-slow-down' import helmet from 'helmet' import { Logger } from 'log4js' @@ -61,6 +62,24 @@ export const createServer = async ( // eslint-disable-next-line @typescript-eslint/no-unsafe-call app.use(helmet()) + // rate limiter/ slow down to many requests + const limiter = slowDown({ + windowMs: 1000, // 1 second + delayAfter: 10, // Allow 10 requests per 1 second. + delayMs: (hits) => hits * 50, // Add 100 ms of delay to every request after the 10th one. + /** + * So: + * + * - requests 1-10 are not delayed. + * - request 11 is delayed by 550ms + * - request 12 is delayed by 600ms + * - request 13 is delayed by 650ms + * + * and so on. After 1 seconds, the delay is reset to 0. + */ + }) + app.use(limiter) + // bodyparser json app.use(json()) // bodyparser urlencoded for elopage diff --git a/backend/yarn.lock b/backend/yarn.lock index 253bbb178..4b4822a2d 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -3225,6 +3225,18 @@ expect@^27.2.5: jest-message-util "^27.2.5" jest-regex-util "^27.0.6" +express-rate-limit@7: + version "7.1.5" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-7.1.5.tgz#af4c81143a945ea97f2599d13957440a0ddbfcfe" + integrity sha512-/iVogxu7ueadrepw1bS0X0kaRC/U0afwiYRSLg68Ts+p4Dc85Q5QKsOnPS/QUjPMHvOJQtBDrZgvkOzf8ejUYw== + +express-slow-down@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/express-slow-down/-/express-slow-down-2.0.1.tgz#60c4515467314675d89c54ec608e2d586aa30f87" + integrity sha512-zRogSZhNXJYKDBekhgFfFXGrOngH7Fub7Mx2g8OQ4RUBwSJP/3TVEKMgSGR/WlneT0mJ6NBUnidHhIELGVPe3w== + dependencies: + express-rate-limit "7" + express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" diff --git a/dlt-connector/package.json b/dlt-connector/package.json index 54a31669a..8b5ae357c 100644 --- a/dlt-connector/package.json +++ b/dlt-connector/package.json @@ -29,6 +29,7 @@ "dlt-database": "file:../dlt-database", "dotenv": "10.0.0", "express": "4.17.1", + "express-slow-down": "^2.0.1", "graphql": "^16.7.1", "graphql-scalars": "^1.22.2", "helmet": "^7.1.0", diff --git a/dlt-connector/src/server/createServer.ts b/dlt-connector/src/server/createServer.ts index 66b9f18b3..50e8d96cb 100755 --- a/dlt-connector/src/server/createServer.ts +++ b/dlt-connector/src/server/createServer.ts @@ -6,6 +6,7 @@ import bodyParser from 'body-parser' import cors from 'cors' import express, { Express } from 'express' // graphql +import { slowDown } from 'express-slow-down' import helmet from 'helmet' import { Logger } from 'log4js' @@ -44,6 +45,24 @@ const createServer = async ( // Helmet helps secure Express apps by setting HTTP response headers. app.use(helmet()) + // rate limiter/ slow down to many requests + const limiter = slowDown({ + windowMs: 1000, // 1 second + delayAfter: 10, // Allow 10 requests per 1 second. + delayMs: (hits) => hits * 50, // Add 100 ms of delay to every request after the 10th one. + /** + * So: + * + * - requests 1-10 are not delayed. + * - request 11 is delayed by 550ms + * - request 12 is delayed by 600ms + * - request 13 is delayed by 650ms + * + * and so on. After 1 seconds, the delay is reset to 0. + */ + }) + app.use(limiter) + await apollo.start() app.use( '/', diff --git a/dlt-connector/yarn.lock b/dlt-connector/yarn.lock index e4a057dd5..6d50426b1 100644 --- a/dlt-connector/yarn.lock +++ b/dlt-connector/yarn.lock @@ -2833,6 +2833,18 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" +express-rate-limit@7: + version "7.1.5" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-7.1.5.tgz#af4c81143a945ea97f2599d13957440a0ddbfcfe" + integrity sha512-/iVogxu7ueadrepw1bS0X0kaRC/U0afwiYRSLg68Ts+p4Dc85Q5QKsOnPS/QUjPMHvOJQtBDrZgvkOzf8ejUYw== + +express-slow-down@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/express-slow-down/-/express-slow-down-2.0.1.tgz#60c4515467314675d89c54ec608e2d586aa30f87" + integrity sha512-zRogSZhNXJYKDBekhgFfFXGrOngH7Fub7Mx2g8OQ4RUBwSJP/3TVEKMgSGR/WlneT0mJ6NBUnidHhIELGVPe3w== + dependencies: + express-rate-limit "7" + express@4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" diff --git a/federation/package.json b/federation/package.json index 0b2809754..1457b1be1 100644 --- a/federation/package.json +++ b/federation/package.json @@ -24,6 +24,7 @@ "decimal.js-light": "^2.5.1", "dotenv": "10.0.0", "express": "4.17.1", + "express-slow-down": "^2.0.1", "graphql": "15.5.1", "graphql-request": "5.0.0", "helmet": "^7.1.0", diff --git a/federation/src/server/createServer.ts b/federation/src/server/createServer.ts index 3a75f6764..97729b882 100644 --- a/federation/src/server/createServer.ts +++ b/federation/src/server/createServer.ts @@ -25,6 +25,7 @@ import { Connection } from '@dbTools/typeorm' import { apolloLogger } from './logger' import { Logger } from 'log4js' import helmet from 'helmet' +import { slowDown } from 'express-slow-down' // i18n // import { i18n } from './localization' @@ -66,6 +67,24 @@ export const createServer = async ( // Helmet helps secure Express apps by setting HTTP response headers. app.use(helmet()) + // rate limiter/ slow down to many requests + const limiter = slowDown({ + windowMs: 1000, // 1 second + delayAfter: 10, // Allow 10 requests per 1 second. + delayMs: (hits) => hits * 50, // Add 100 ms of delay to every request after the 10th one. + /** + * So: + * + * - requests 1-10 are not delayed. + * - request 11 is delayed by 550ms + * - request 12 is delayed by 600ms + * - request 13 is delayed by 650ms + * + * and so on. After 1 seconds, the delay is reset to 0. + */ + }) + app.use(limiter) + // bodyparser json app.use(express.json()) // bodyparser urlencoded for elopage diff --git a/federation/yarn.lock b/federation/yarn.lock index 7a9ec6814..74cc04521 100644 --- a/federation/yarn.lock +++ b/federation/yarn.lock @@ -2624,6 +2624,18 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" +express-rate-limit@7: + version "7.1.5" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-7.1.5.tgz#af4c81143a945ea97f2599d13957440a0ddbfcfe" + integrity sha512-/iVogxu7ueadrepw1bS0X0kaRC/U0afwiYRSLg68Ts+p4Dc85Q5QKsOnPS/QUjPMHvOJQtBDrZgvkOzf8ejUYw== + +express-slow-down@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/express-slow-down/-/express-slow-down-2.0.1.tgz#60c4515467314675d89c54ec608e2d586aa30f87" + integrity sha512-zRogSZhNXJYKDBekhgFfFXGrOngH7Fub7Mx2g8OQ4RUBwSJP/3TVEKMgSGR/WlneT0mJ6NBUnidHhIELGVPe3w== + dependencies: + express-rate-limit "7" + express@4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"