Rate Limiting — express-rate-limit, brute force himoyasi

~15 daq · Express · Autentifikatsiya va Xavfsizlik

Muammodan boshlaylik

Hacker login endpointingizga sekundiga 10,000 so'rov yuboradi — har xil parollarni sinab ko'radi. Bu — brute force hujumi. Yetarli vaqt berilsa — parolni topadi.

Yoki kimdir API ingizni skript bilan chaqirib, serveringizni zo'riqtiradi — boshqa foydalanuvchilar uchun sekinlashadi. Bu — DoS (Denial of Service).

Rate Limiting — bir IP dan ma'lum vaqt ichida nechta so'rov qabul qilinishini cheklash.

npm install express-rate-limit

Asosiy ishlatish

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 daqiqa
  max:      100,             // 15 daqiqada maksimal 100 so'rov
  message:  { message: 'Juda ko\'p so\'rov. 15 daqiqadan keyin qayta urinib ko\'ring.' },
  standardHeaders: true,  // RateLimit-* headerlarini qo'shish
  legacyHeaders:   false,
});

app.use(limiter); // barcha route lar uchun

Bir IP dan 15 daqiqada 100 tadan ko'p so'rov kelsa — 429 Too Many Requests qaytariladi.


Login uchun qattiqroq limit

Barcha route uchun 100 so'rov yetarli. Lekin login uchun — ancha qattiqroq bo'lishi kerak. Brute force hujumida hacker ko'p urinish qiladi.

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 daqiqa
  max:      5,               // 15 daqiqada faqat 5 urinish
  message:  { message: 'Juda ko\'p urinish. 15 daqiqadan keyin qayta urinib ko\'ring.' },
  skipSuccessfulRequests: true, // muvaffaqiyatli so'rovlar hisoblanmaydi
});

router.post('/login', loginLimiter, async (req, res, next) => {
  // ...
});

skipSuccessfulRequests: true — to'g'ri parol bilan kirish hisoblanmaydi. Faqat muvaffaqiyatsiz urinishlar cheklanadi.


Turli endpointlar uchun turli limitlar

// Umumiy limit — barcha route lar
const generalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max:      100,
});

// API limit — authenticated so'rovlar uchun
const apiLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 daqiqa
  max:      60,        // sekundiga 1 so'rov
});

// Login limit — brute force himoyasi
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max:      5,
});

app.use(generalLimiter);
app.use('/api', apiLimiter);
app.post('/auth/login', loginLimiter, loginHandler);

Redis bilan — bir nechta server

Standart bo'yicha rate limit ma'lumotlari xotirada saqlanadi. Bir nechta server bo'lsa — har biri o'z hisobini yuritadi. Hacker 10 ta serverga so'rov yuborsa — har birida 5 ta urinish, jami 50 ta.

Redis bilan — barcha serverlar bir xil hisobni ko'radi:

npm install rate-limit-redis
const RedisStore = require('rate-limit-redis');
const redis      = require('./redis');

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max:      5,
  store:    new RedisStore({ sendCommand: (...args) => redis.call(...args) }),
});

Tez-tez uchraydigan xatolar

Faqat global limit qo'yish:

app.use(rateLimit({ max: 100 }));
// Login uchun ham 100 — brute force uchun yetarli

Muhim endpointlar (login, register, parol tiklash) uchun alohida, qattiqroq limit.

Proxy ortida IP noto'g'ri aniqlanishi:

Nginx yoki load balancer ortida ishlasangiz — barcha so'rovlar bir IP dan kelayotgandek ko'rinadi. Barcha foydalanuvchilar bir limitni bo'lishadi.

app.set('trust proxy', 1); // bitta proxy
const limiter = rateLimit({ ... });

Xulosa

Rate Limiting — bir IP dan ma'lum vaqt ichida so'rovlar sonini cheklash. Brute force va DoS hujumlaridan himoya.

Umumiy limit — barcha route lar uchun. Login uchun — ancha qattiqroq (5-10 urinish). Bir nechta server bo'lsa — Redis store.


Keyingi dars

28-dars: CORS — nima, qanday sozlanadi, credentials, whitelist