Skip to content

Commit 9aa1bfe

Browse files
committed
Add rate limits to auth endpoints
1 parent 2998efb commit 9aa1bfe

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

api/package-lock.json

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"@sentry/node": "^4.6.1",
4343
"auth0": "^4.3.1",
4444
"express": "^4.18.2",
45+
"express-rate-limit": "^7.4.1",
4546
"ipaddr.js": "^2.1.0",
4647
"jsonwebtoken": "^9.0.2",
4748
"lodash": "^4.17.21",

api/src/server.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as http from 'http';
22
import express = require('express');
33
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
44
import * as log from 'loglevel';
5+
import rateLimit from 'express-rate-limit';
56

67
import { getCorsResponseHeaders } from './cors';
78
import { configureAppProxyTrust } from './trusted-xff-ip-setup';
@@ -86,6 +87,14 @@ apiRouter.use((req, _res, next) => {
8687
next();
8788
});
8889

90+
const RATE_LIMIT_PARAMS = {
91+
max: 10,
92+
windowMs: 60 * 60 * 1000, // 1h window
93+
message: { error: 'Too many login attempts, please try again after 1 hour' },
94+
standardHeaders: true,
95+
legacyHeaders: false
96+
};
97+
8998
apiRouter.get('/get-prices', lambdaWrapper('get-prices'));
9099
apiRouter.get('/get-app-data', lambdaWrapper('get-app-data'));
91100
apiRouter.get('/get-billing-data', lambdaWrapper('get-billing-data'));
@@ -96,9 +105,12 @@ apiRouter.post('/paypro-webhook', lambdaWrapper('paypro-webhook'));
96105
apiRouter.get('/redirect-to-checkout', lambdaWrapper('redirect-to-checkout'));
97106
apiRouter.get('/redirect-paypro-to-thank-you', lambdaWrapper('redirect-paypro-to-thank-you'));
98107

99-
apiRouter.post('/auth/send-code', lambdaWrapper('auth/send-code'));
100-
apiRouter.post('/auth/login', lambdaWrapper('auth/login'));
101-
apiRouter.post('/auth/refresh-token', lambdaWrapper('auth/refresh-token'));
108+
apiRouter.post('/auth/send-code', rateLimit(RATE_LIMIT_PARAMS), lambdaWrapper('auth/send-code'));
109+
apiRouter.post('/auth/login',
110+
rateLimit({ ...RATE_LIMIT_PARAMS, skipSuccessfulRequests: true }), // Just limiting failed codes
111+
lambdaWrapper('auth/login')
112+
);
113+
apiRouter.post('/auth/refresh-token', rateLimit(RATE_LIMIT_PARAMS), lambdaWrapper('auth/refresh-token'));
102114

103115
apiRouter.post('/update-team', lambdaWrapper('update-team'));
104116
apiRouter.post('/update-team-size', lambdaWrapper('update-team-size'));

0 commit comments

Comments
 (0)