Skip to content

Commit

Permalink
feat: implement rate limiter and sanitize input (#694)
Browse files Browse the repository at this point in the history
  • Loading branch information
abretonc7s authored Feb 22, 2024
1 parent dbf2e3a commit 3c07a52
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/security-code-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
docs/
e2e/
tests/
packages/development-tools/
'**/mocks/'
'**/__snapshots__/'
'**/*.test.js*'
Expand Down
1 change: 1 addition & 0 deletions packages/sdk-socket-server-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-rate-limit": "^7.1.5",
"helmet": "^5.1.1",
"ioredis": "^5.3.2",
"lru-cache": "^10.0.0",
Expand Down
18 changes: 17 additions & 1 deletion packages/sdk-socket-server-next/src/api-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Analytics from 'analytics-node';
import bodyParser from 'body-parser';
import cors from 'cors';
import express from 'express';
import { rateLimit } from 'express-rate-limit';
import helmet from 'helmet';
import { createClient } from 'redis';
import { logger } from './logger';
Expand All @@ -17,15 +18,25 @@ const THIRTY_DAYS_IN_SECONDS = 30 * 24 * 60 * 60; // expiration time of entries

const app = express();

const limiter = rateLimit({
windowMs: 5 * 60 * 1000, // 5 minutes
limit: 100, // Limit each IP to 100 requests per `window` (here, per 5 minutes).
standardHeaders: 'draft-7', // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
// store: ... , // Use an external store for consistency across multiple server instances.
});

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.options('*', cors());
app.use(helmet());
app.disable('x-powered-by');
// Apply the rate limiting middleware to all requests.
app.use(limiter);

async function inspectRedis(key?: string) {
if (key) {
if (key && typeof key === 'string') {
const value = await redisClient.get(key);
logger.debug(`inspectRedis Key: ${key}, Value: ${value}`);
}
Expand Down Expand Up @@ -70,6 +81,11 @@ app.post('/evt', async (_req, res) => {
logger.debug(`Received event /debug`, body);

const id: string = body.id || 'socket.io-server';

if (typeof id !== 'string') {
return res.status(400).json({ status: 'error' });
}

let userIdHash = await redisClient.get(id);

if (!userIdHash) {
Expand Down
1 change: 1 addition & 0 deletions packages/sdk-socket-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-rate-limit": "^7.1.5",
"helmet": "^5.1.1",
"ioredis": "^5.3.2",
"lru-cache": "^10.0.0",
Expand Down
18 changes: 17 additions & 1 deletion packages/sdk-socket-server/src/api-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Analytics from 'analytics-node';
import bodyParser from 'body-parser';
import cors from 'cors';
import express from 'express';
import { rateLimit } from 'express-rate-limit';
import helmet from 'helmet';
import { createClient } from 'redis';
import { logger } from './logger';
Expand All @@ -17,15 +18,25 @@ const THIRTY_DAYS_IN_SECONDS = 30 * 24 * 60 * 60; // expiration time of entries

const app = express();

const limiter = rateLimit({
windowMs: 5 * 60 * 1000, // 5 minutes
limit: 100, // Limit each IP to 100 requests per `window` (here, per 5 minutes).
standardHeaders: 'draft-7', // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
// store: ... , // Use an external store for consistency across multiple server instances.
});

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.options('*', cors());
app.use(helmet());
app.disable('x-powered-by');
// Apply the rate limiting middleware to all requests.
app.use(limiter);

async function inspectRedis(key?: string) {
if (key) {
if (key && typeof key === 'string') {
const value = await redisClient.get(key);
logger.debug(`inspectRedis Key: ${key}, Value: ${value}`);
}
Expand Down Expand Up @@ -70,6 +81,11 @@ app.post('/evt', async (_req, res) => {
logger.debug(`Received event /debug`, body);

const id: string = body.id || 'socket.io-server';

if (typeof id !== 'string') {
return res.status(400).json({ status: 'error' });
}

let userIdHash = await redisClient.get(id);

if (!userIdHash) {
Expand Down
11 changes: 11 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8277,6 +8277,7 @@ __metadata:
eslint-plugin-node: ^11.1.0
eslint-plugin-prettier: ^3.4.0
express: ^4.18.2
express-rate-limit: ^7.1.5
helmet: ^5.1.1
ioredis: ^5.3.2
jest: ^29.6.4
Expand Down Expand Up @@ -8333,6 +8334,7 @@ __metadata:
eslint-plugin-node: ^11.1.0
eslint-plugin-prettier: ^3.4.0
express: ^4.18.2
express-rate-limit: ^7.1.5
helmet: ^5.1.1
ioredis: ^5.3.2
jest: ^29.6.4
Expand Down Expand Up @@ -24298,6 +24300,15 @@ __metadata:
languageName: node
linkType: hard

"express-rate-limit@npm:^7.1.5":
version: 7.1.5
resolution: "express-rate-limit@npm:7.1.5"
peerDependencies:
express: 4 || 5 || ^5.0.0-beta.1
checksum: bdf6ddf4f8c8659d31de6ec1f088b473b2cb4180eb09ae234a279c88744832276e5c1482d530875110c90e314b51a7720bcfb2b3139c1b9e6bf652ba4b59f192
languageName: node
linkType: hard

"express@npm:^4.17.3, express@npm:^4.18.2":
version: 4.18.2
resolution: "express@npm:4.18.2"
Expand Down

0 comments on commit 3c07a52

Please sign in to comment.