Giriş denemelerini sınırlama
Güvenlik · Zorluk 5/5 · JavaScript · 42 satırKöken: Kurgu
Görev
Yapay zekâdan istenen
POST /login için hesap başına deneme sınırı yaz. Bir hesapta 15 dakika içinde 5 başarısız denemeden sonra, ilk başarısız denemenin üzerinden 15 dakika geçene kadar o hesaba gelen her deneme, şifre doğru olsa bile 429 almalı. Başarılı giriş sayacı sıfırlar; yanlış şifre 401 alır. E-postada büyük-küçük harf önemsizdir; users.findUser da harfe bakmadan arar. Servis tek bir Node.js sürecinde çalışır; eski kayıtları başka bir iş temizler. Hangi e-postanın kayıtlı olduğunu gizlemek bu görevin kapsamında değil.
Teslim notu
Yapay zekâ kodu teslim ederken şunu yazdı:
“Kaba kuvvet denemelerine karşı hesap başına sınır eklendi: 15 dakikada 5 başarısız denemeden sonra 429 dönüyor. Deneme ilk await'ten önce sayıldığı için aynı anda gelen istekler de sınırı aşamıyor.”
Yapay zekânın yazdığı kod
JavaScript42 satırHatalı bulduğun satırları işaretle; her işarete önem seç ve nedenini bir cümleyle yaz.
Satıra tıkla ya da dokun. Klavyede satıra gidip Enter'a bas.
Önem nasıl seçilir
- KritikVeri kaybı, güvenlik açığı ya da para kaybı
- ÖnemliGörevin istediği bir durumda kullanıcı yanlış sonuç alır
- KüçükGörevin dışında kalan nadir bir uç durum ya da okunurluk
Test konusunda önem, testin yakalamadığı hatalı uygulamanın etkisine göre belirlenir.
Gerekçe puanlanmaz; sonuçta örnek cevapla karşılaştırırsın.
const MAX_FAILED_ATTEMPTS = 5;const WINDOW_MS = 15 * 60 * 1000;/** * @typedef {{ id: string, passwordHash: string }} User * @typedef {{ count: number, since: number }} Attempts *//** * POST /login with a limit on failed attempts per account. * * @param {{ findUser(email: string): Promise<User | null> }} users * Finds a user by email, ignoring letter case. * @param {(password: string, hash: string) => Promise<boolean>} verify * @param {Map<string, Attempts>} attempts Shared by all requests. */export function createLogin(users, verify, attempts) { /** * @param {string} email * @param {string} password * @param {number} now Milliseconds since the epoch. */ return async function login(email, password, now) { const key = email.trim(); let entry = attempts.get(key); if (entry === undefined || now - entry.since >= WINDOW_MS) { entry = { count: 0, since: now }; attempts.set(key, entry); } entry.count += 1; const user = await users.findUser(key); if (user !== null && (await verify(password, user.passwordHash))) { attempts.delete(key); return { status: 200, userId: user.id }; } if (entry.count > MAX_FAILED_ATTEMPTS) { return { status: 429 }; } return { status: 401 }; };}Kanıtlayan test
Doğru seçenek, bu kodda başarısız olan, yani hatayı ortaya çıkaran testtir.
Gönderince sayaca yedi bilgi gider; gerekçe metnin cihazında kalır. Veriler